You could probably just make member_id and charity_comp_id unique by enforcing a UNIQUE index on that table, any attempt to add another row then throws a particular mysql error message upon whose appearance you can fork your code, generate a warning or log it etc.
That'll save the extra query to see if a record exists every time you get a bone fide vote (ie the vast majority of the time, no?)
As far as votes go, at least in this situation, I would probably go with the insert ignore option. What would be the point of showing an error? If they've already voted on that one, just let them move on. I wouldn't want to stop the flow of what they're doing (for usability reasons) just to tell them something as simple as "You've already voted for this". I'm sure they won't care enough about that to justify the interruption in their workflow.
As far as resources go... there wouldn't be much difference in performance. You're hitting the DB either way. Either to check if the vote is already there, or to perform an insert that never actually happens.
Another option would be to check if they've voted for that charity already when the user loads the page. Then you could grey-out/disable the voting option so they can't vote. Then they'd already know that they've voted on it before they try to vote again. You can combine that with the insert ignore option on the back end to prevent them from manually going to vote.php?charity_id=1 (or whatever your URL scheme is) and voting again when you've disabled the vote link.