Mysql уникальный индекс для системы голосования - PullRequest
0 голосов
/ 21 февраля 2012

В таблице для записи голосов на сообщениях как

CREATE TABLE votes
(
vote_id int(11) NOT NULL AUTO_INCREMENT,
post_id int(11) REFERENCES posts(post_id) ON DELETE CASCADE,
user_id int(11) REFERENCES users(user_id) ON DELETE SET NULL,
vote ENUM('Up', 'Down'),
ip varchar(255),
UNIQUE INDEX (on which???)
PRIMARY KEY(vote_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci

Как добавить UNIQUE INDEX, чтобы избежать дублирования голосования?Если избиратель является пользователем, UNIQUE INDEX должен применяться к (post_id, user_id);и если не пользователь, UNIQUE INDEX должен применяться к (post_id, ip).

На самом деле мне нужно иметь UNIQUE INDEX только для (post_id, user_id) ИЛИ (post_id, ip);но НЕ оба.

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Пересмотрено после получения дополнительной информации Чтобы сделать именно так, как вы просите, я бы посоветовал следующее. Добавьте исходную таблицу для дальнейшей нормализации

CREATE TABLE vote_sources (
    source_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    // 0 will be treated as anonymous, as NULL can have issues on UNIQUE indexes
    user_id INT(11) UNSIGNED NOT NULL REFERENCES users(user_id) ON DELETE SET 0,
    ip VARCHAR(15) NOT NULL,
    dupeCheck VARCHAR(15) NOT NULL,
    PRIMARY KEY(source_id),
    UNIQUE INDEX (dupeCheck)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci

CREATE TABLE votes
(
    vote_id int(11) NOT NULL AUTO_INCREMENT,
    post_id int(11) REFERENCES posts(post_id) ON DELETE CASCADE,
    source_id int(11) NOT NULL REFERENCES vote_sources(source_id) ON DELETE CASCADE,
    vote ENUM('Up', 'Down'),
    PRIMARY KEY(vote_id),
    UNIQUE INDEX(post_id,source_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci

А потом бороться с двойными проверками этого триггера

CREATE TRIGGER dupeSourceCheck
BEFORE INSERT ON vote_sources
FOR EACH ROW SET NEW.dupeCheck = IF(NEW.user_id>0,CAST(NEW.user_id AS CHAR),NEW.ip)

Что, в свою очередь, должно приводить к ошибке дублирующегося ключа, если дублированный источник детализирован, при этом все еще отображается числовой идентификатор_пользователя для более эффективных объединений.

2 голосов
/ 21 февраля 2012

Рекомендую нормализовать: создайте другое поле, например vote_src VARCHAR(15), которое получит из вашего кода либо пользователя, либо IP-адрес, и создайте уникальный индекс для этого.

0 голосов
/ 21 февраля 2012

У вас есть PHPMyAdmin? Это очень легко сделать там. Вы хотите, чтобы поле было ПЕРВИЧНЫМ КЛЮЧОМ или вы действительно хотите просто УНИКАЛЬНЫЙ индекс? Если у вас есть PHPMyAdmin в качестве опции, вы можете перейти на вкладку своей структуры и внизу вы увидите таблицу индексов с возможностью добавить индекс. Нажмите «GO» и Walla! У вас есть свой индекс.

...