реализация UNIQUE в связанных таблицах в MySQL - PullRequest
3 голосов
/ 21 сентября 2009

ПОЛЬЗОВАТЕЛЬ - ЧЕЛОВЕК, и ЧЕЛОВЕК имеет КОМПАНИЮ - пользователь -> человек один к одному, человек -> компания много к одному.

person_id - это FK в таблице USER. company_id - это FK в таблице PERSON.

ЧЕЛОВЕК не может быть ПОЛЬЗОВАТЕЛЕМ, но ПОЛЬЗОВАТЕЛЬ всегда является ЧЕЛОВЕКОМ.

Если бы company_id был в пользовательской таблице, я мог бы создать уникальный ключ на основе имени пользователя и company_id, но это не так, и в этом случае было бы дублирование данных.

В настоящее время я реализую правило уникального имени пользователя / идентификатора компании в коде оболочки менеджера RoseDB, но оно кажется неправильным. Я хотел бы определить уникальное правило на уровне БД, если смогу, но я не уверен, как именно к нему подойти. Я пробовал что-то вроде этого:

alter table user add unique(used_id,person.company_id);

но это не работает.

Прочитав документацию, я не могу найти пример, который делает что-то даже отдаленно похожее. Я пытаюсь добавить функциональность, которой не существует, или я что-то здесь упускаю?

Ответы [ 3 ]

1 голос
/ 21 сентября 2009

Вы можете определить ограничение UNIQUE в таблице Person:

CREATE TABLE Company (
 company_id SERIAL PRIMARY KEY
) ENGINE=InnoDB;

CREATE TABLE Person (
 person_id SERIAL PRIMARY KEY,
 company_id BIGINT UNSIGNED,
 UNIQUE KEY (person_id, company_id),
 FOREIGN KEY (company_id) REFERENCES Company (company_id)
) ENGINE=InnoDB;

CREATE TABLE User (
 person_id BIGINT UNSIGNED PRIMARY KEY,
 FOREIGN KEY (person_id) REFERENCES Person (person_id)
) ENGINE=InnoDB;

Но на самом деле вам не нужно уникальное ограничение даже в таблице Person, потому что person_id уже само по себе уникально. Нет никакого способа, которым данное person_id могло бы сослаться на две компании.

Так что я не уверен, какую проблему вы пытаетесь решить.


Ваш комментарий:

Это не решает проблему того, что одно и то же имя пользователя может существовать в разных компаниях.

То есть вы хотите, чтобы данное имя пользователя было уникальным в пределах одной компании, но могло бы использоваться в разных компаниях? Это было не ясно мне из вашего первоначального вопроса.

Так что если у вас нет других атрибутов, специфичных для пользователей, я бы объединил пользователя с персоной и добавил бы столбец "is_user". Или просто полагаться на то, что неявно верно, что Персона с ненулевым криптопазом по определению является Пользователем.

Тогда ваша проблема с ограничениями кросс-таблицы UNIQUE исчезнет.

1 голос
/ 21 сентября 2009

Есть ли еще атрибуты в вашей таблице PERSON? Причина, по которой я спрашиваю, заключается в том, что вы хотите реализовать типичную таблицу следствий:

USERS таблица:

  • user_id (pk)

USER_COMPANY_XREF (урожд. ЛИЦО) Таблица:

  • user_id (pk, fk)
  • company_id (pk, fk)
  • EFFECTIVE_DATE (не нуль)
  • EXPIRY_DATE (не ноль)

COMPANIES таблица:

  • company_id (pk)

Первичный ключ таблицы USER_COMPANY_XREF, представляющий собой составной ключ USERS.user_id и COMPANIES.company_id, позволит вам связать пользователя с несколькими компаниями, не дублируя данные в USERS таблицы, и обеспечить ссылочную целостность.

1 голос
/ 21 сентября 2009

Ну, нет ничего простого , которое делает то, что вы хотите. Вы, вероятно, можете применить требуемое ограничение, используя BEFORE INSERT и BEFORE UPDATE триггеры . См. этот SO вопрос о возникновении ошибок MySQL , чтобы узнать, как справиться с ошибкой триггеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...