2011-01-25 4 views
4

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

product1_table: 
    id, 
    name, 
    category, 
    ...other fields 

product2_table: 
    id, 
    name, 
    category, 
    ...other fields 

product_to_category_table: 
    product_id, 
    category_id 

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

UPDATE:

Многие люди предложили таблица наследования (или генераторной спецификации). Это вариант, о котором я знаю, но предоставленный в других системах баз данных. Я мог бы поделиться последовательностью между таблицами. Я надеялся, что MySQL имеет аналогичное решение. Я предполагаю, что это не основано на ответах. Думаю, мне придется пойти с наследованием стола ... Спасибо всем.

+0

ли MySql последовательности или столбцы Autonumber? –

+0

Да, обычной практикой для первичных ключей является столбец «auto_increment». – chaos

+0

Столбцы Auto_increment принимают любые параметры, такие как START или STEP? –

ответ

8

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

product_table 
    id 
    name 
    category 
    general_fields... 

product_type1_table: 
    id 
    product_id 
    product_type1_fields... 

product_type2_table: 
    id 
    product_id 
    product_type2_fields... 

product_to_category_table: 
    product_id 
    category_id 

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

+0

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

+0

Это не сложность. Это делает это намного проще. Вы пытаетесь, чтобы все версии имели один и тот же PK? –

+1

У меня недостаточно информации, чтобы узнать, почему это проблема; все, что для меня значит, что у вас есть уникальный ключ на 'имя, версия', а не просто' name'. – chaos

0

Вы не можете «поделиться» с первичным ключом.

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

Другой вариант - иметь модель наследования, где у вас есть таблица с одним продуктом, а затем две таблицы подтипов продукта, которые ссылаются на основную таблицу продуктов и имеют собственный специализированный набор полей. Запрос этой модели более болезнен, чем отдельная таблица IMHO, поэтому я рассматриваю ее как менее желательный вариант.

+0

Это действительно не должно быть недостатком трех табличной модели; Я могу посмотреть, как выглядит одна таблица ... вуаля! простой запрос. Я не совсем согласен, просто скажу « –

4

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

Это упрощает поиск основного продукта для идентификаторов и имен по категориям.

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

+0

Yup. Простое соотношение «1 к 1». Только «главная» таблица должна иметь auto_incrementing PK. – Mchl

+0

Я не думаю, что дизайн объединяет одну категорию ... см. Мое объяснение ниже – Andrew

+0

@Andrew: На самом деле, выглядит как _both_ одной категории в названии продукта _and_ таблицы, чтобы разрешить несколько категорий для каждого продукта. В любом случае проблема категории является вторичной по отношению к макету таблиц продуктов. –

1

Кажется, что вы ищете наследование таблицы.

Вы можете использовать общую таблицу product с атрибутами, общими для обоих product1 и product2, а также атрибут type, который может быть либо "product2" или "product1"

Тогда таблицы product1 и product2 бы все их специфические признаки и ссылки на род стол product.

product: 
    id, 
    name, 
    category, 
    type 

product1_table: 
    id, 
    #product_id, 
    product1_specific_fields 

product2_table: 
    id, 
    #product_id, 
    product2_specific_fields 
0

Ваше объяснение немного расплывчатое, но от моего основного понимания я был бы соблазн сделать это

Таблица продукта содержит общие поля

product 
------- 
product_id 
name 
... 

таблица product_extra1 и таблицу product_extra2 содержат разные поля эти таблицы habe взаимно однозначные отношения, действующие между product.product_id и product_extra1.product_id и т. д. Примените отношения «один к одному», установив product_id в таблицах внешнего ключа (product_extra1 и т. д.), чтобы быть уникальным, используя уникальное ограничение. вам нужно будет принято решение о бизнес-правилах относительно того, как эти данные заселен

product_extra1 
--------------- 
product_id 
extra_field1 
extra_field2 
.... 

product_extra2 
--------------- 
product_id 
different_extra_field1 
different_extra_field2 
.... 

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

1

Прежде всего позвольте мне заявить, что я согласен со всем, что сказал Хаос, Ларри и Фил.

Но если вы настаиваете на другом пути ...

Есть две причины, по которым вы поделились ПК. Одна уникальность в двух таблицах и две для полной ссылочной целостности.

Я не уверен, что именно «последовательность» имеет поддержку столбцов Auto_increment. Кажется, есть system setting, чтобы определить прирост по значению, но ничего за столбец.

Что бы я делал в Oracle, просто разделите одну и ту же последовательность между двумя таблицами. Другим методом было бы установить значение STEP 2 в auto_increment и начать одно в 1, а другое - в 2. В любом случае вы генерируете уникальные значения между ними.

Вы можете создать третью таблицу, в которой нет ничего, кроме столбца PK. Этот столбец также может предоставить параметр «Автозапуск», если нет способа создания пропущенного автономера внутри одного сервера. Затем на каждой из ваших таблиц данных вы добавляете триггеры CRUD. Вставка в любую таблицу данных сначала инициирует вставку в таблицу псевдо-индекса (и возвращает идентификатор для использования в локальной таблице). Аналогично, удаление из локальной таблицы инициирует удаление из таблицы псевдо индексов. Любые таблицы детей, которые должны указывать на родителя, указывают на эту таблицу псевдо-индекса.

Обратите внимание, что это должно быть триггер в строке и будет замедлять работу на этих таблицах. Но таблицы типа «продукт», как правило, не имеют очень высокой скорости DML. Любой, кто жалуется на «эффект воздействия», составляет не учитывая масштаб.

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

+0

Я мог бы использовать общую последовательность в PostgreSQL, но MySQL, похоже, не имеет эквивалента. Я также пытаюсь избежать уродливого «иметь запасную таблицу для хранения следующего значения ключа». – Endophage

+1

Ну, вы не можете избежать всякого предложения ... в какой-то момент вы должны танцевать с тем, кто брел я. –

+0

И общая последовательность по-прежнему не покупает вас RI. Вам всегда нужен одиночный ПК, если вы хотите получить твердый RI. –

Смежные вопросы