Как осуществить uniques через несколько таблиц

У меня есть следующие таблицы в сервере MySQL:

Companies:
- UID (unique)
- NAME
- other relevant data

Offices:
- UID (unique)
- CompanyID
- ExternalID
- other data

Employees:
- UID (unique)
- OfficeID
- ExternalID
- other data

В каждом из них UID является уникальным идентификатором, созданным базой данных.

Существуют внешние ключи для обеспечения ссылок между Сотрудником-> Office-> Компания на UID.

Поля ExternalID в Офисах и Сотрудниках являются идентификатором, предоставленным моему приложению Компанией (мой клиент (клиенты) на самом деле). Клиенты не имеют (и не заботьтесь) о моих собственных идентификаторах и всех данных мое приложение получает от них, определяется только на основе их идентификаторов (т.е. ExternalID в моих таблицах).

Т.е. запрос от клиента на псевдоязыке похож, "я - Компания X, обновляю данные для моего сотрудника Y".

Я должен осуществить уникальность на комбинации CompanyID и Сотрудников. ExternalID, таким образом, в моей базе данных не будет никакого дублирующегося ExternalID для сотрудников той же компании.

Я думал приблизительно 3 возможных решения:

  1. Измените схему для Сотрудников для включения CompanyID, и создать уникальный ограничивают на этих двух полях.

  2. Осуществите триггер, которые на обновляют/вставляют в Сотрудниках, проверяет уникальность.

  3. Осуществите проверку на прикладном уровне (т.е. мой сервис получения).

Мой alternative-dbadmin-in-me Саис, который (3) является худшим решением, поскольку он не защищает базу данных несоответствия в случае ошибки приложения или чего-то еще, и по всей вероятности будет самым медленным.

Триггерное решение может быть тем, что я хочу, но это может стать сложным, особенно если несколько вставляют/обновляют потребность, которая будет выполнена в отдельном операторе, и я не уверен в производительности по сравнению с (1).

И (1) взгляды самый быстрый и самый легкий подход, но отчасти идет вразрез с моим пониманием реляционной модели.

Что, ТАКИМ ОБРАЗОМ, мнение экспертов DB о за и против каждого из подходов, особенно если существует возможность для добавления дополнительного уровня абстракции - т.е. Компания-> Office-> Отдел-> Сотрудник, и та же уникальность должна быть сохранена (Компания/Сотрудник).

5
задан OMG Ponies 18 February 2010 в 22:36
поделиться

3 ответа

Это действительно просто комментарий к "Use Crockford 's JSON.stringify" Джейсона Бантинга, но я не смог добавить комментарий к этому ответу.

Как отмечено в комментариях, JSON.stringify плохо играет с библиотекой Prototype (www.prototypejs.org). Тем не менее, довольно легко сделать так, чтобы они играли хорошо вместе, временно удалив метод Array.prototype.toJSON, который добавляет прототип, запустить Crockford 's stringify (), а затем положить его обратно так:

  var temp = Array.prototype.toJSON;
  delete Array.prototype.toJSON;
  $('result').value += JSON.stringify(profile_base, null, 2);
  Array.prototype.toJSON = temp;
-121--2034484-

Я не могу рекомендовать достаточно Eric Sink' s Source CONTROL HHOWTO . Это даст вам ответы, которые вы ищете, и хорошее понимание системы управления версиями в целом.

-121--4195931-

Вы правы - # 1 - лучший вариант.
Конечно, я бы поставил его под сомнение на первый взгляд (из-за ярлыков), но знание бизнес-правила, чтобы гарантировать, что сотрудник связан только с одной компанией - это имеет смысл.

Кроме того, у меня есть внешний ключ, связывающий идентификатор компании в таблице сотрудников с идентификатором компании в таблице офиса. В противном случае сотрудник может быть связан с компанией без офиса. Если это не приемлемо...

Триггеры являются крайним средством, если связь не может быть продемонстрирована в модели данных, а обслуживание логики из приложения означает, что логика централизована - нет возможности возникновения плохих данных, если кто-то не снимает ограничения (что означает, что у вас есть большие проблемы).

3
ответ дан 15 December 2019 в 00:59
поделиться

Установите auto_increment_increment на количество таблиц, которое у вас есть. SET auto_increment_increment = 3; (возможно, вы захотите установить это в вашем my.cnf)

Затем вручную установите начальное значение auto_increment для каждой таблицы в разные значения первая таблица - 1, вторая таблица - 2, третья таблица - 3

Таблица 1 будет иметь значения 1,4,7,10,13 и т.д.

Таблица 2 будет иметь значения 2,5,8,11,14 и т.д.

Таблица 3 будет иметь значения 3,6,9,12,15 и т.д.

Конечно, это только ОДИН вариант, лично я бы просто сделал это значение комбинированным. Это может быть просто TableID, AutoincrementID, где TableID является постоянным во всех строках.

0
ответ дан 15 December 2019 в 00:59
поделиться

Каждая из ваших таблиц, предоставленных компанией, должна включать CompanyID в `UNIQUE KEY' над предоставленными компанией идентификаторами.

Ссылочная целостность должна использовать предоставленные компанией идентификаторы:

CREATE TABLE company (
        uid INT NOT NULL PRIMARY KEY,
        name TEXT
        );

CREATE TABLE office (
        uid INT NOT NULL PRIMARY KEY,
        companyID INT NOT NULL,
        externalID INT NOT NULL,
        UNIQIE KEY (companyID, externalID),
        FOREIGN KEY (companyID) REFERENCES company (uid)
        );

CREATE TABLE employee (
        uid INT NOT NULL PRIMARY KEY,
        companyID INT NOT NULL,
        officeID INT NOT NULL,
        externalID INT NOT NULL,
        UNIQIE KEY (companyID, externalID),
        FOREIGN KEY (companyID) REFERENCES company(uid)
        FOREIGN KEY (companyID, officeID) REFERENCES office (companyID, externalID)
        );

и т.д.

1
ответ дан 15 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: