Дизайн базы данных: нужны уникальные строки + отношения

Скажем, у меня есть следующая таблица:

TABLE: product
============================================================
| product_id | name         | invoice_price | msrp         |
------------------------------------------------------------
| 1          | Widget 1     | 10.00         | 15.00        |
------------------------------------------------------------
| 2          | Widget 2     | 8.00          | 12.00        |
------------------------------------------------------------

В этой модели product_id — это ПК, на который ссылается ряд других таблиц.

У меня есть требование, чтобы каждая строка была уникальной. В примере about строка определяется как столбцы name, invoice_price и msrp. (В разных таблицах могут быть разные определения того, какие столбцы определяют «строку».)

ВОПРОСЫ:

  1. В приведенном выше примере следует ли сделать name, invoice_price и msrp составным ключом, чтобы гарантировать уникальность каждой строки?
  2. Если ответ на № 1 «да», это будет означать, что текущий ПК, product_id, не будет определен как ключ; скорее, это будет просто автоматически увеличивающийся столбец. Будет ли этого достаточно для использования другими таблицами для создания связей с определенными строками в таблице product?

Обратите внимание, что в некоторых случаях в таблице может быть 10 или более столбцов, которые должны быть уникальными. Это будет много столбцов, определяющих составной ключ! Это плохо?

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


person StackOverflowNewbie    schedule 04.04.2011    source источник


Ответы (3)


Если у вас много столбцов, для которых нужно создать уникальный ключ, создайте свой собственный «ключ», используя данные из столбцов в качестве источника. Это означало бы создание ключа на прикладном уровне, но база данных «обеспечивала бы» уникальность. Простым методом было бы использовать хэш md5 всех наборов данных для записи в качестве вашего уникального ключа. Тогда у вас есть только один фрагмент данных, который нужно использовать в отношениях.

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

person Brent Baisley    schedule 04.04.2011
comment
Ой! Это не приходило мне в голову. Это может быть значительно лучшим решением. Это связано со стоимостью хеширования каждый раз, когда я вставляю, но это может быть дешевле, чем иметь много индексов. Как вы думаете? - person StackOverflowNewbie; 05.04.2011
comment
Стоимость хеширования минимальна, особенно md5. Индексированные данные фиксированной длины на самом деле быстрее для поиска в больших наборах данных. Но не похоже, что вы будете использовать для этого большие наборы данных. - person Brent Baisley; 05.04.2011

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

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

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

У вас может быть что-то вроде этого (очевидно, не используйте * в рабочем коде)

# get the lowest price for an item that's currently active
select * 
from product p 
where p.name = "widget 1" # a non-primary index on product.name would be advised
  and p.active
order-by sale_price ascending 
limit 1
person corsiKa    schedule 04.04.2011

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

person Rasika    schedule 04.04.2011