Составной уникальный ключ, в котором один из столбцов содержит многозначные значения - PullRequest
0 голосов
/ 07 июня 2018

У меня есть таблица, в которой определенные свойства (столбцы) определяют запись как уникальную.Например, таблица ведения записей книги может иметь следующий дизайн:

Таблица книг:

id (автоинкрементный, bigint, уникальный, первичный ключ)

title

author_id

... другие столбцы

Публикация таблицы:

id (автоинкрементный, bigint, уникальный, первичный ключ)

book_id (int, fkey to book.id)

publishing_company_id (int, fkey to company.id)

publishing_date

... другие столбцы

Этот дизайн сделан при условии, что компания не может публиковать одну и ту же книгу более одного раза в одну и ту же дату.Поэтому я установил уникальный составной ключ, содержащий столбцы [book_id, publishing_company_id, publishing_date].До сих пор все понятно.

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

book_id = 12

publishing_company_id = 145

publishing_date = 2018-02-09

language = spa

цена = 25

и

book_id = 12

publishing_company_id = 145

публикация_дата = 2018-02-09

язык = ru

цена = 30

Если язык - единственное, что отличает записи (цена одинакова), записи могут быть сохранены отдельно, как указано выше, или объединены в одну запись:

book_id = 12

publishing_company_id = 145

publishing_date = 2018-02-09

language = spa, en

price = 25

Проблема с этим дизайном заключается в том, что, если мы создадим запись книги на нескольких языках(en, spa, fr, de, nl, jp), а затем идентичная запись с перекрывающимися языками (spa, fr, sq), он распознает их как разныеарендные записи, так как значение языка не идентично.Вместо этого я хотел бы избежать двух записей одной книги на одном языке.Таким образом, языки spa и fr могут существовать только в одной из приведенных выше записей, в то время как язык sq может быть отдельной записью, если его еще нет в другой записи той же публикации.

Подводя итог,вместо поиска идентичных совпадений для столбцов составного ключа, я хотел бы искать идентичные совпадения для некоторых столбцов и сравнение «Мне нравится» для некоторых других, которое ищет перекрытие значений.

Я могу(и будет) обрабатывать это на уровне приложения, но я хотел бы также поддерживать ту же логику в дизайне базы данных.

Есть ли способ сделать это?

...