Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Юзать или не Юзать составные PrimaryKey?


Автор: Lamak 3.11.2006, 11:33
На моей новой работе юзают много разных БД  

Так вот
(1) в базах часто используются таблицы у которых PrimaryKey состоит из 3-х ,5-ти, а то и 7-ми полей.
(2) а ещё  есть таблицы с 20-30 полями.
 
Моё мнение:  ето бардак - плохо спроектированые БД

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

универ,книги - это по теории
на работе    - это на практике
Поетому я и сомневаюсью  
Получается что теория и практика расходятся smile 

Вопрос:
Так рекомендуется или не ракомендуется юзать составные PrimaryKey?
Люди поделитесь своим  опытом! Неужели у вас тоже встречаются такие таблицы(с (1) и (2)) 

Автор: LSD 3.11.2006, 11:45
В общем случае: выборка данных по составному PK дольше, индексы занимают больше места и как следствие памяти сервера. Поэтому когда есть возможность использовать простой PK, то лучше использовать его.

Но иногда составной PK бывает и полезным. В частности: уникальный ID записи для всех таблиц базы, или даже уникальный в пределах нескольких баз (нужно для репликации данных). Или вынести в PK некое условие, по которому часто осуществляется фильтрация данных.

Автор: JUmPER 3.11.2006, 11:49
если есть составной ключ из нескольких полей, то лучше (в целях оптимизации и удобочитаемости)
завести таблицу соответствий простой ключ <--> составной ключ
и вместо составнго юзать соответствующий ему простой...

Автор: skyboy 3.11.2006, 12:16
Цитата(Lamak @  3.11.2006,  10:33 Найти цитируемый пост)
в базах часто используются таблицы у которых PrimaryKey состоит из 3-х ,5-ти, а то и 7-ми полей.

потенциально - плохо; но лучше смотреть "по ситуации". У меня немало таблиц с PK на два поля. 
Цитата(Lamak @  3.11.2006,  10:33 Найти цитируемый пост)
а ещё  есть таблицы с 20-30 полями.

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

Автор: chief39 5.11.2006, 16:00
Составные - правильнее с т.з. теории.
Но если это строки.. и полей несколько...
Сам понимаешь, с интежером ни в какое сравнение по скорости...
Лучше "по соседству" влепить на эти значимые столбцы уникальный констрейнт.
А при выборках пользовать интежер в качестве примари ки.

Везде, где работал, на больших продакшнах именно так и делали.
Но это лишь моя точка зрения 

Автор: Shiny 6.11.2006, 12:26
Lamak, очень многое зависит от проекта и его назначения.
Есть проекты, в которых невозможно обойтись без составных ключей (та же репликация), есть проекты, в которых таблицах которых нужны именно 20-30 полей (например детальные анкетные данные о человеке - адрес, телефон, дата рождения - человек один, разбивать на мелкие таблички не нужно)
В общем, я считаю, что ты слишком пытаешься обобщить ситуацию под теорию.
Разберись в сути проектов и приведи более детальный пример - тогда можно будет говорить более конкретно.

Автор: chief39 6.11.2006, 13:27
Вобщем, 
Цитата(Shiny @  6.11.2006,  12:26 Найти цитируемый пост)
очень многое зависит от проекта и его назначения.

Цитата(Lamak @  3.11.2006,  11:33 Найти цитируемый пост)
(1) в базах часто используются таблицы у которых PrimaryKey состоит из 3-х ,5-ти, а то и 7-ми полей.

За редкими исключениями - это плохо с т.з. производительности. Желателен служебный ID.


А вот тут следует хорошо подумать:
Цитата(Lamak @  3.11.2006,  11:33 Найти цитируемый пост)
(2) а ещё  есть таблицы с 20-30 полями.

Цитата(Shiny @  6.11.2006,  12:26 Найти цитируемый пост)
есть проекты, в которых таблицах которых нужны именно 20-30 полей (например детальные анкетные данные о человеке - адрес, телефон, дата рождения - человек один, разбивать на мелкие таблички не нужно)

нужны то нужны...
Но следовало бы оценить частоту использования конкретных данных.

Иногда следует применять вертикально разбиение таблицы:
ФИО, паспорт, некий код etc. - держать в первой таблице.
Во вторую вынести год рождения, адрес,  дату регистрации, прописку, семейное положение и прочую мелочь. Связать их отношением 1 к 1 по искусственному примари ки.

Если 90% запросов - просто список людей без дополнительных данных - скорость возрастёт.
А остальные 10% запросов вполне могут делать джоин этих таблиц в одну.
Опять-таки, можно посадить вьюху, которая будет представлять как бы неразбитую таблицу джойном.

Вполне возможно, что стоит разбить таблички для скорости....

http://www.olap.ru/basic/saharov.asp немного написано по этому поводу smile



Автор: Shiny 6.11.2006, 14:10
Цитата(chief39 @  6.11.2006,  12:27 Найти цитируемый пост)
Но следовало бы оценить частоту использования конкретных данных.
Опять же - зависит от проекта.
У меня одинаково часто запрашивали инфу как по параметрам "пол-возраст", "город - месяц рождения", "тип населённого пункта - наличие домашнего телефона" и т.д. и т.п.
Заморачиваться с разделением не стоило - никакой выгоды не вижу, приоритетные поля выделить нельзя.
Поэтому всё равно считаю что всё зависит от конкретного проекта smile

Цитата(chief39 @  6.11.2006,  12:27 Найти цитируемый пост)
За редкими исключениями - это плохо с т.з. производительности. Желателен служебный ID.

Составной праймари кей необходимен для правильной обработки данных, полученных с реплицированных баз. Служебный АйДи(ГУИД) добавляет сам сервер, но использовать его для последующего анализа нереально - это всё равно что varchar(16), скорость обработки нулевая.... 
Другое дело что потом для правильной работы того же олапа нужно делать из 4-х полей составного ключа одно уникальное вычисляемое поле, а это уже кто как исхитрится smile

Автор: chief39 6.11.2006, 15:39
Цитата(Shiny @  6.11.2006,  14:10 Найти цитируемый пост)
Поэтому всё равно считаю что всё зависит от конкретного проекта

Ессно smile
(
Цитата(chief39 @  6.11.2006,  13:27 Найти цитируемый пост)
Если 90% запросов - просто список людей без дополнительных данных - скорость возрастёт.

)


Цитата(Shiny @  6.11.2006,  14:10 Найти цитируемый пост)
Служебный АйДи(ГУИД) добавляет сам сервер, но использовать его для последующего анализа нереально - это всё равно что varchar(16), скорость обработки нулевая.... 

Я говорил о простом интежере, который создан нами и не несёт никакой информации реального мира. Но является уникальным.
И добавляет его не сам сервер, а мы. Нашими механизмами.

Вроде как номер паспорта для человека: вроде бы никакой инфы о человеке толком - но уникален для него везде и вполне переносим.

Автор: Shiny 6.11.2006, 17:08
Цитата(chief39 @  6.11.2006,  14:39 Найти цитируемый пост)
Я говорил о простом интежере, который создан нами и не несёт никакой информации реального мира. Но является уникальным.
И добавляет его не сам сервер, а мы. Нашими механизмами.

Согласна - работает для всех НЕреплицируемых баз.
Для них можно даже и на сервер положиться - айдентити при отсутствии репликации меня ещё не подводило.
Для реплицируемых - фикус smile

Автор: chief39 6.11.2006, 17:27
Цитата(Shiny @  6.11.2006,  17:08 Найти цитируемый пост)
Согласна - работает для всех НЕреплицируемых баз.
Для них можно даже и на сервер положиться - айдентити при отсутствии репликации меня ещё не подводило.
Для реплицируемых - фикус

Угу smile

Автор: TaNK 11.11.2006, 13:15
я например считаю юзать PK - необходимо, но не так чтобы их было слишком много, их должно быть столько скоко необходимо для работы с базой, для добавления, изменения и удаления....с InterBase хвататет и пару ключей, один PK и парочку FK

Автор: Romkin 14.11.2006, 16:51
TaNK,  Что значит "не слишком много"? И что значит "с InterBase хвататет и пару ключей, один PK и парочку FK"? Чем этот сервер БД так уж отличается от всего остального?
На таблицу может быть один PK. И желательно, чтобы он всегда был. Иначе потом будет немного больно ;)
Идея, что нужно иметь в первичный ключе одно поле, и при этом автоинкремент, пришла из файловых БД - там за целостностью ручками следить надо было. 
Естественно, искусственные ключи нужны. Но и составные - тоже нужны, в связке мастер-деталь. У меня иногда получается иерархия до 4-5 деталей, последовательно, т.е. Мастер -> Деталь -> Деталь ... И если бы я делал в каждой детали простой ключ из одного автоинкрементного поля - ну это просто нарушение целостности! Как понять, какому мастеру принадлежит деталь N-го уровня?! 
Я считаю, что уж идентифицирующая связь должна приводить к автоматическому наследованию PK мастера в PK зависимой таблицы. И такие соображения, что индексы получаются объемными тут, имхо, вообще не должны приводиться: нормальная БД справится. Зато запросы будут гораздо проще.

Автор: LSD 14.11.2006, 17:09
Цитата(Romkin @  14.11.2006,  16:51 Найти цитируемый пост)
Естественно, искусственные ключи нужны. Но и составные - тоже нужны, в связке мастер-деталь. У меня иногда получается иерархия до 4-5 деталей, последовательно, т.е. Мастер -> Деталь -> Деталь ... И если бы я делал в каждой детали простой ключ из одного автоинкрементного поля - ну это просто нарушение целостности! Как понять, какому мастеру принадлежит деталь N-го уровня?! 

1. При чем тут нарушение целостности? foreign key на что?
2. Если в середине этой цепочки один child сменит parent-а, то всю нижележащую цепочку править?

Автор: Romkin 14.11.2006, 17:55
Цитата(LSD @  14.11.2006,  17:09 Найти цитируемый пост)
1. При чем тут нарушение целостности? foreign key на что?
2. Если в середине этой цепочки один child сменит parent-а, то всю нижележащую цепочку править?

Нарушение логической целостности: глядя на запись подчиненной таблицы можно определить только запись непосредственного предка. 
То есть, я имею в виду случай, когда 
1. имеется иерархия подчинения
2. на каждом уровне первичный ключ - простой уникальный идентификатор
3. имеется ссылка только на непосредственного предка.
И получается, что для того, чтобы найти группировку более высокого уровня, требуется пройти всю цепочку. А если ключ наследуется по порядку - четко видно всю иерархию, и промежуточные уровни можно опускать.
При этом возникает два случая:
а. Связь по альтернативному ключу. Зачем? Как раз лишний индекс и образуется.
б. Связь неидентифицирующая (в детали ссылка на мастера не входит в первичный ключ). Но это же совсем не то, что подразумевалось! Это - не связь мастер-деталь, это лукап.

А насчет смены парента - вообще говоря, идентифицирующая связь не предполагает этого. Например, возьмем простой документ, счет, состоящий из заголовка и содержимого. Явная связь мастер-деталь. И пересоединять содержимое документа к другому заголовку - достаточно бессмыссленная операция.
Разумеется, бывают и другие случаи - но в этих случаях смена парента - редкая операция, тут можно и поправить. Тем более, что и делать-то ничего не надо особо: констрейнт обновит автоматом.

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

Автор: LSD 14.11.2006, 18:02
Что-то я не пойму твою мысль. Дай пример таблиц, ключей и констрайнов.

Автор: Dremlin 14.11.2006, 18:14
LSD, а чего там не понять?

ты делаешь:

tbl1(id1), tbl2(id2, id1), tbl3(id3, id2), tbl4(id4, id3)... etc

, а человеку удобнее:

tbl1(id1), tbl2(id2, id1), tbl3(id3, id2, id1), tbl4(id4, id3, id2, id1)... etc

хотя смысл подобных манипуляций от меня ускользает...  smile 

Автор: Romkin 14.11.2006, 18:39
Цитата(Dremlin @  14.11.2006,  18:14 Найти цитируемый пост)
tbl1(id1), tbl2(id2, id1), tbl3(id3, id2, id1), tbl4(id4, id3, id2, id1)... etc

Сорри, наоборот (первичные ключи):
tbl1(id1), tbl2(id1, id2), tbl3(id1, id2, id3), tbl4(id1, id2, id3, id4)...
В результате, при возникновении вопроса "мне нужны записи из tbl4, которые относятся к данной записи из tbl1 (то есть известно значение id1)", достаточно смотреть только на tbl4 smile

Автор: LSD 14.11.2006, 22:02
Т.е. в tbl4 - колонки (id1, id2, id3, id4) будут составным первичным ключем? А какие будут foreign key?

Автор: Romkin 14.11.2006, 22:18
Так они очевидны - первичный ключ предка smile
Например, у tbl4 это (id1, id2, id3), унаследованная часть первичного ключа.

Автор: LSD 14.11.2006, 22:27
А foreign key?

Автор: Romkin 14.11.2006, 23:38
я о foreign key и говорю smile
Вот например отрывок:
Код

create table tbl3 (
  id1 integer not null,
  id2 integer not null,
  id3 integer not null,
  constraint PK_tbl3 primary key (id1, id2, id3),
  constraint FK_tbl3_tbl2 foreign key (id1, id2)
    references tbl2 (id1, id2)
    on update cascade
    on delete cascade
);

create table tbl4 (
  id1 integer not null,
  id2 integer not null,
  id3 integer not null,
  id4 integer not null,
  constraint PK_tbl4 primary key (id1, id2, id3, id4),
  constraint FK_tbl4_tbl3 foreign key (id1, id2, id3)
    references tbl3  (id1, id2, id3)
    on update cascade
    on delete cascade
);

и тд.

Автор: LSD 15.11.2006, 00:05
Теперь возник вопрос: зачем надо было включать id1 и id2 в primary key?
Простой пользователь не должен синтетические ключи видеть вообще, а DBA не так уж и часто надо любоваться на PK, индекс по такому ключу менее эффективен. Вообщем я вижу только недостатки.

Автор: Romkin 15.11.2006, 09:37
Я уже сказал: упрощаются запросы. Это как минимум. 
Например, если возникает задача выбрать записи из tbl4, которые принадлежат определенной записи из tbl1, в моем случае нужно сделать простой запрос к tbl4, id1 там есть и индексировано.
Если бы этих полей не было, пришлось бы делать join трех таблиц, это - чтение трех индексов.
Простой пользователь, разумеется, ключи не видит, а разработчик - у меня несколько людей смотрит структуру БД. И когда, смотря на таблицу, ты можешь сразу сказать, какое место в иерархии она занимает и с какими таблицами соединена, имхо, это большой плюс.
ТО, что индекс менее эффективен - а насколько? Во сколько раз индекс по 4 полям integer менее эффективен, чем по 1-2?

Автор: LSD 15.11.2006, 11:11
Цитата(Romkin @  15.11.2006,  09:37 Найти цитируемый пост)
Я уже сказал: упрощаются запросы. Это как минимум. 
Например, если возникает задача выбрать записи из tbl4, которые принадлежат определенной записи из tbl1, в моем случае нужно сделать простой запрос к tbl4, id1 там есть и индексировано.

Каким образом включение id1, id2, id3 в primary key упрощает запросы?

Добавлено @ 11:12 
Цитата(Romkin @  15.11.2006,  09:37 Найти цитируемый пост)
ТО, что индекс менее эффективен - а насколько? Во сколько раз индекс по 4 полям integer менее эффективен, чем по 1-2?

Это зависит от кучи факторов, и просто так сказать, что он менее эффективен в 2,36 раза нельзя.

Автор: Romkin 15.11.2006, 12:44
Цитата(LSD @  15.11.2006,  11:11 Найти цитируемый пост)
Каким образом включение id1, id2, id3 в primary key упрощает запросы?

Рассмотрим следующий скрипт (примерный, многие поля в таблицах опущены):
Код

сreate table tbl1 (    
  id1 integer not null,    
  name varchar(30) not null,
  constraint PK_tbl1 primary key (id1)    
);
сreate table tbl2 (    
  id1 integer not null,    
  id2 integer not null,    
  constraint PK_tbl2 primary key (id1, id2),    
  constraint FK_tbl2_tbl1 foreign key (id1)    
    references tbl1 (id1)    
    on update cascade    
    on delete cascade    
);
сreate table tbl3 (    
  id1 integer not null,    
  id2 integer not null,    
  id3 integer not null,    
  constraint PK_tbl3 primary key (id1, id2, id3),    
  constraint FK_tbl3_tbl2 foreign key (id1, id2)    
    references tbl2 (id1, id2)    
    on update cascade    
    on delete cascade    
);    
create table tbl4 (    
  id1 integer not null,    
  id2 integer not null,    
  id3 integer not null,    
  id4 integer not null,    
  price numeric(18,2),
  constraint PK_tbl4 primary key (id1, id2, id3, id4),    
  constraint FK_tbl4_tbl3 foreign key (id1, id2, id3)    
    references tbl3  (id1, id2, id3)    
    on update cascade    
    on delete cascade    
);


Задача:
Вывести из tbl1 Name и для каждого Name показать его сумму Price из таблицы tbl4.
Решение: 
Код

select tbl1.Name, (select sum(tbl4.Price) from tbl4 where tbl4.id1 = tbl1.id1) from tbl1;
или
select tbl1.Name, sum(tbl4.Price) from tbl1 left join tbl4 on tbl1.id1 = tbl4.id1 group by tlb1.name;


Теперь рассмотрим другой скрипт, где ссылки - только на непосредственного предка:
Код

сreate table tbl1 (    
  id1 integer not null,    
  name varchar(30) not null,
  constraint PK_tbl1 primary key (id1)    
);
сreate table tbl2 (    
  id2 integer not null,    
  id1 integer not null,    
  constraint PK_tbl2 primary key (id2),    
  constraint FK_tbl2_tbl1 foreign key (id1)    
    references tbl1 (id1)    
    on update cascade    
    on delete cascade    
);
сreate table tbl3 (    
  id3 integer not null,    
  id2 integer not null,    
  constraint PK_tbl3 primary key (id3),    
  constraint FK_tbl3_tbl2 foreign key (id2)    
    references tbl2 (id2)    
    on update cascade    
    on delete cascade    
);    
create table tbl4 (    
  id4 integer not null,    
  id3 integer not null,    
  price numeric(18,2),
  constraint PK_tbl4 primary key (id4),    
  constraint FK_tbl4_tbl3 foreign key (id3)    
    references tbl3  (id3)    
    on update cascade    
    on delete cascade    
);

Нужно то же самое. Можно, я не буду писать запрос с join всех этих таблиц?
У меня получается, что в первом варианте скорость выше, несмотря на то, что индекс используется частично. На практике, конечно, немного сложнее (у меня tbl2 - соединение многие-многие двух таблиц, там еще другие запросы), но запросы иногда нужны примерно такие.

Автор: LSD 15.11.2006, 13:02
Я не об этом.
В это топике обсуждается составные primary key, а не организация foreign key. Я спрашивал зачем нужно было включать поля id1, id2, id3 в primary key, а не зачем ты их добавил в таблицу tbl4 или сделал по ним foreign key.

По поводу эффективности, не скажу за все СУБД, но в Oracle вот такой primary key:
Код
constraint PK_tbl4 primary key (id1, id2, id3, id4)

будет использоваться только если идет запрос по первым полям, т.е.: id1 или id1, id2 или id1, id2, id3 или id1, id2, id3, id4. Если выборка идет по другой комбинации полей (например id2, id3), то индекс использоваться не будет, и будет full scan.

Автор: Romkin 15.11.2006, 13:52
Цитата(LSD @  15.11.2006,  13:02 Найти цитируемый пост)
По поводу эффективности, не скажу за все СУБД, но в Oracle вот такой primary key:

код SQL    
1:    
constraint PK_tbl4 primary key (id1, id2, id3, id4)    

будет использоваться только если идет запрос по первым полям, т.е.: id1 или id1, id2 или id1, id2, id3 или id1, id2, id3, id4. Если выборка идет по другой комбинации полей (например id2, id3), то индекс использоваться не будет, и будет full scan.


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

Цитата(LSD @  15.11.2006,  13:02 Найти цитируемый пост)
В это топике обсуждается составные primary key, а не организация foreign key. Я спрашивал зачем нужно было включать поля id1, id2, id3 в primary key, а не зачем ты их добавил в таблицу tbl4 или сделал по ним foreign key.

Хм. А кто начал спрашивать в десять вечера, какие foreign key у меня есть? smile 
Включаю я их в PK для по нескольким причинам: 
1. Это набор полей, однозначно идентифицирующий запись. Можно заметить, я нигде не упоминал, что все они автоинкрементные. На мой взгляд, подобную иерархию на автоинкрементах и представить-то сложно smile В реальности tbl2 у меня, к примеру - соединение многие-многие двух таблиц. Зачем мне там автоинкремент? Первичный ключ в этом случае автоматически получается конкатенацией ПК этих таблиц...
2. Для сохранения целостности: этим я явно показываю, какие записи могут быть в таблице. Разумеется, можно сделать, напрмиер в tbl4 один ключ id4 (если, подчеркиваю, это автоинкремент) и сделать ограничение уникальности (альтернативный ключ). Но это мне не надо: тогда индекс первичный ключа вообще в запросах участвовать не будет! Он не несет нужной информации. Только при выборке на клиент данной записи для редактирования, разве что (я не заржавею, написав для этого условие по 4 полям для составного ключа).
3. Для указания разработчику, с чем повязана эта таблица и как. Включение этих полей в ПК сразу подразумевает, что это именно подчиненная таблица, связь идентифицирующая, и вся работа с ней должна проходить с использованиемее предков. Плюс - перемещение записи между предками либо недопускается в реальности, либо чрезвычайно редкий сервис (я уже приводил пример, счет, состоящий из заголовка и содержимого. Нафиг содержимое перемещать? Или, например, это просто детализация записи мастера - тоже перемещать нет смысла). Конечно, разработчик всегда может посмотреть на схему данных, полная - на стене висит, два листа А0. И есть поблочная, листиков 30 А4... Как показывает прктика, уж лучше чтобы БД максимально подсказывала, что в ней есть.
4. Как показывает практика, выборки при схеме с составными ключами идут практически все по ним! Либо по первым полям, либо по всем. Немногие исключения - именно при унаследованной связи многие-многие, например, рассмотрим частично модифицированную схему:
Код

сreate table tbl3 (     
  id1 integer not null,     
  id2 integer not null,     
  id3 integer not null,     
  constraint PK_tbl3 primary key (id1, id2, id3),     
  constraint FK_tbl3_tbl2 foreign key (id1, id2)     
    references tbl2 (id1, id2)     
    on update cascade     
    on delete cascade,
  constraint FK_tbl3_tblN foreign key (id3)     
    references tblN (id3)     
    on update cascade     
);    
create table tbl4 (     
  id1 integer not null,     
  id2 integer not null,     
  id3 integer not null,     
  id4 integer not null,     
  price numeric(18,2),    
  constraint PK_tbl4 primary key (id1, id2, id3, id4),     
  constraint FK_tbl4_tbl3 foreign key (id1, id2, id3)     
    references tbl3  (id1, id2, id3)     
    on update cascade     
    on delete cascade     
);
create index idx_tbl4_tblN on tbl4 (id3, id4);

Обращаю внимание: tbl3 - фактически связь двух таблиц, tbl2 и tblN (не показана, первичный ключ id3) поэтому в tbl4 унаследованы поля из этих же таблиц. При возникновении задачи "выбрать все поля из tbl4 для данной записи в tblN" поиск по первичному ключу не пойдет, поэтому введен индекс, второе поле в котором для, эээ... у меня id4 не автоинкремент, и тоже участвует, как правило, в запросах smile. 

Автор: chief39 15.11.2006, 14:00
Цитата(LSD @  15.11.2006,  13:02 Найти цитируемый пост)
По поводу эффективности, не скажу за все СУБД,

В большинстве. Может, есть исключения, но я их пока не знаю...

Автор: LSD 16.11.2006, 12:44
Цитата(Romkin @  15.11.2006,  13:52 Найти цитируемый пост)
Хм. А кто начал спрашивать в десять вечера, какие foreign key у меня есть?

Я уже понял, что это было опрометчиво smile

Мне не нравится:
  • UPDATE на первичный ключ в случае перемещений к другому родителю (если данные реплицируются, то будут проблемы)
  • мне не нравится навешивание какой-то логики на первичный ключ
    Цитата(Romkin @  15.11.2006,  13:52 Найти цитируемый пост)
    Для указания разработчику, с чем повязана эта таблица и как. Включение этих полей в ПК сразу подразумевает, что это именно подчиненная таблица, связь идентифицирующая, и вся работа с ней должна проходить с использованиемее предков.

    все таки первичный ключ это просто уникальный идентификатор записи, а у нас уже получается нечто вроде естественного ключа
  • в случае больших зависимостей будет много лишних полей



Автор: Romkin 16.11.2006, 14:39
Цитата(LSD @  16.11.2006,  12:44 Найти цитируемый пост)
UPDATE на первичный ключ в случае перемещений к другому родителю (если данные реплицируются, то будут проблемы)

Возможно. Смотря какая методика репликации. У меня в основной задаче вообще репликацию не сделаешь, не имеет смысла smile
При перемещении к другому родителю особых проблем не вижу, апдейтятся же первичные ключи подчиненных таблиц, кому какое дело, какое у них значение?
И как сделать связь многие-многие без конкатенации первичных ключей связываемых таблиц в таблицу связи? При этом же никого не пугает, что при перемещении он модифицируется...
 
Цитата(LSD @  16.11.2006,  12:44 Найти цитируемый пост)
мне не нравится навешивание какой-то логики на первичный ключ

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

Цитата(LSD @  16.11.2006,  12:44 Найти цитируемый пост)
все таки первичный ключ это просто уникальный идентификатор записи, а у нас уже получается нечто вроде естественного ключа

В какой-то мере - да. Но опять же не вижу особых причин так не делать. Ограничение уникальности должно быть, почему нужно его делать не первичным ключем (при условии, что данные-то не изменятся)? У меня все поля в РК - статичны. Ну почти все ;)

Цитата(LSD @  16.11.2006,  12:44 Найти цитируемый пост)
в случае больших зависимостей будет много лишних полей

На самом деле, это не так. Я тоже ожидал большого количества полей при проектировании, но, как правило, их 4-5 получается максимально. Да, у меня есть пара таблиц с количеством полей в ключе 6-7, но это, скорее, исключение. Как правило, получается, что связи идут так, что поля сливаются.

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

Автор: Shaggie 20.6.2007, 08:09
Почитал... интересно... есть вопрос.

Предположим, существует такая БД:
  • Таблица "следователь"
  • Таблица "дело"

Логично предположить, что между ними организованиа связь по типу many-to-many.

Поэтому создаётся дополнительная таблица "Следователь_Дело", в которой находятся ссылки на первичные ключи двух основных таблиц.

Как наиболее эффективно организовать эти ссылки? Создать независимый первичный ключ, а ссылки представить в виде foreign key? Или НЕ СОЗДАВАТЬ отдельный первичный ключ, а реализовать его за счёт композитного ключа этих двух ссылок?

Автор: LSD 20.6.2007, 09:28
Цитата(Shaggie @  20.6.2007,  09:09 Найти цитируемый пост)
Логично предположить, что между ними организованиа связь по типу many-to-many.

Разве одно дело могут вести два следователя?


Цитата(Shaggie @  20.6.2007,  09:09 Найти цитируемый пост)
Как наиболее эффективно организовать эти ссылки? Создать независимый первичный ключ, а ссылки представить в виде foreign key? Или НЕ СОЗДАВАТЬ отдельный первичный ключ, а реализовать его за счёт композитного ключа этих двух ссылок?

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

Автор: Shaggie 20.6.2007, 09:30
Спасибо, я понял

Автор: Deniz 21.6.2007, 06:00
LSD, 
Цитата(LSD @  20.6.2007,  12:28 Найти цитируемый пост)
Разве одно дело могут вести два следователя?

Могут, не одновременно, в некотором промежутке времени, причем дело может и к первому вернуться, и нужно хранить всю историю.
Вот была http://www.ibase.ru/devinfo/NaturalKeysVersusAtrificialKeysByTentser.html давно, но все же

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)