Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сомневаюсь в нужности Foreign Key, Обсудить 
:(
    Опции темы
JavaCraft
  Дата 20.4.2007, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



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

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

Достоинства внешних ключей:
1) Не обязательно следить за корректностью операций удаления или изменения записей.

Недостатки:
1)  В следствие необязательности контроля за корректностью операций удаления или изменения записей
 многие запросы будут обрабатываться впустую, расходуя ресурсы сервера, а исключительные события будут тормозить программу, как это имеет место при любой обработке исключений.

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

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

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

Что думает уважаемый All по этому поводу? 

PM MAIL   Вверх
SergeBS
Дата 23.4.2007, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



JavaCraft, 
Ответь себе на вопрос: откуда берутся внешние ключи и почему без них практически невозможно обойтись? Намек: БД без справочников не бывает. Заодно поймешь, что всякие сбои - выдуманная тобой проблема.

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

А не рано? Может вначале в общих принципах разобраться? Чтобы потом не переделывать все по новой.

PM MAIL   Вверх
Бонифаций
Дата 23.4.2007, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 827
Регистрация: 15.9.2005
Где: Brisbane

Репутация: 20
Всего: 40



Если у Вас половина таблиц myisam половина innodb - как вы собираетесь FK применять?



--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
JavaCraft
Дата 2.5.2007, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



Цитата(SergeBS @  23.4.2007,  08:36 Найти цитируемый пост)
А не рано?

 smile Не рано.
Цитата(SergeBS @  23.4.2007,  08:36 Найти цитируемый пост)
почему без них практически невозможно обойтись?

Если к собственной логике относиться не критично, т.е., по вашему, то обойтись невозможно, это точно.
PM MAIL   Вверх
JavaCraft
Дата 2.5.2007, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



Цитата(Бонифаций @  23.4.2007,  09:46 Найти цитируемый пост)
Если у Вас половина таблиц myisam половина innodb - как вы собираетесь FK применять?

Между InnoDB. Для MyISAM таблиц FK не нужны. Это справочники только для чтения. В модели FK к ним строятся, но метятся как не реализуемые, в реализации отключаются за ненадобностью.
ТОлько я всё больше убеждаюсь, что FK и для InnoDB не нужны, поскольку модель данных почти всегда требует прямой проверки условий внутри хранимых процедур и функций. Каскадное удаление в моей задаче в принципе не нужно, удалять справочные данные без проверки я не собираюсь. 

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

Это сообщение отредактировал(а) JavaCraft - 2.5.2007, 12:11
PM MAIL   Вверх
SergeBS
Дата 2.5.2007, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



JavaCraft, 
Объясняю без намеков: если нет справочников, то и нет необходимости в FK. Но тогда получившееся изделие БД назвать нельзя - это будет просто сборище разнородных таблиц. 
Если справочники есть, то "ручками" связывать их с нужными таблицами - мартышкин труд. Надежнее и проще чем FK не придумаешь, поскольку они для реализации этой связи и созданы.

Добавлено через 2 минуты и 45 секунд
Цитата
ТОлько я всё больше убеждаюсь, что FK и для InnoDB не нужны, поскольку модель данных почти всегда требует прямой проверки условий внутри хранимых процедур и функций. 

А нука подробнее, на примере. Без заумных размышлений.
PM MAIL   Вверх
JavaCraft
Дата 2.5.2007, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



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

Цитата(SergeBS @  2.5.2007,  15:33 Найти цитируемый пост)
Но тогда получившееся изделие БД назвать нельзя - это будет просто сборище разнородных таблиц. 

Я так понимаю. По вашему деление на базы и не базы следует вести по признаку наличия и отсутствия FK?

Цитата(SergeBS @  2.5.2007,  15:33 Найти цитируемый пост)
А нука подробнее, на примере. Без заумных размышлений. 

Что-то типа такого
Код

...
DECLARE _id INT DEFAULT NULL;
SELECT id INTO _id FROM Table1 WHERE id_parent=<Параметр> LIMIT 1;
...
 IF _id IS NOT NULL THEN # или так IF NOT EXISTS(SELECT id INTO _id FROM Table1 WHERE id_parent=<Параметр> LIMIT 1) THEN
    # еще проверки если нужно
    # и наконец
    DELETE FROM Table2 WHERE id=<Параметр>;
 ELSE
    # другое действие
    # и другие проверки
 END IF;

И разные варианты такого
Код

select * from Table1 t1 inner join Table2 t2 ON t2.id_parent=t1.id where t1.id = <Параметр>


Цитата(SergeBS @  2.5.2007,  15:33 Найти цитируемый пост)
Если справочники есть, то "ручками" связывать их с нужными таблицами - мартышкин труд. Надежнее и проще чем FK не придумаешь, поскольку они для реализации этой связи и созданы.

Покажите как оно должно быть по взрослому. Тоже код плиз.

PM MAIL   Вверх
SergeBS
Дата 3.5.2007, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



JavaCraft, 
Цитата
Я так понимаю. По вашему деление на базы и не базы следует вести по признаку наличия и отсутствия FK?

Настоятельно рекомендую все-таки прочитать и понять, что такое нормальные формы. Поскольку все на самом деле ОЧЕНЬ просто: 
1. БД без применения нормализации не бывает. Более понятно (упрощенно): нет БД без справочников.
2. Если есть справочник, то есть FK. Любой другой подход - просто попытки носить воду в решете.
Если очень хочется дальше спорить - пожалуйста. Только это спор не со мной, а с Дейтом, Ульманом, Коддом и т.п. И я сильно сомневаюсь, что новичок в СУБД сумеет придумать что-то умнее и лучше, чем то, что наработано профессионалами за полвека.

Цитата
Покажите как оно должно быть по взрослому. Тоже код плиз.

На. Таблица жителей
Код

/****** Object:  Table [dbo].[gitel]    Script Date: 03.05.2007 10:01:55 ******/
CREATE TABLE [dbo].[gitel] (
    [gitel_id] [int] IDENTITY (1, 1) NOT NULL ,
    [nom_d] [int] NOT NULL ,
    [otn_nomer] [tinyint] NOT NULL ,
    [fm] [varchar] (30) NULL ,
    [im] [varchar] (20) NULL ,
    [ot] [varchar] (20) NULL ,
    [dtr] [smalldatetime] NULL ,
    [pas_ser] [varchar] (4) NULL ,
    [pas_nom] [varchar] (6) NULL ,
    [pas_tip] [varchar] (7) NULL ,
    [pas_place_cod] [smallint] NULL ,
    [pas_dat] [smalldatetime] NULL ,
    [pens_nom] [varchar] (6) NULL ,
    [cod_rods] [tinyint] NOT NULL ,
    [sem] [char] (1) NOT NULL ,
    [fact_adr] [char] (1) NOT NULL ,
    [cod_stat] [tinyint] NULL ,
    [cod_lgot] [smallint] NOT NULL ,
    [dop_text] [varchar] (30) NULL ,
    [lgot_doc] [smallint] NOT NULL ,
    [lgot_text] [varchar] (30) NULL ,
    [cod_type_min] [tinyint] NOT NULL ,
    [doh_sum] [decimal](8, 3) NOT NULL ,
    [cod_prav] [tinyint] NULL ,
    [prav_doc] [smallint] NOT NULL ,
    [prav_text] [varchar] (30) NULL ,
    [s_dopoln] [decimal](5, 1) NOT NULL ,
    [comment1] [varchar] (300) NULL ,
    [place_name] [varchar] (50) NULL ,
    [cod_tip] [varchar] (8) NULL ,
    [d_vvod] [smalldatetime] NULL ,
    [cod_user] [tinyint] NULL ,
    [sem_nomer] [tinyint] NULL 
) ON [PRIMARY]
GO

Один из справочников для нее - степень родства с основным квартиросъемщиком.. 
Код

CREATE TABLE [dbo].[rods] (
    [cod] [tinyint] IDENTITY (1, 1) NOT NULL ,
    [name] [varchar] (30) NOT NULL ,
    [d_vvod] [smalldatetime] NOT NULL ,
    [cod_user] [tinyint] NULL 
) ON [PRIMARY]
GO


FK_gitel_rods:
Primary Key Table:      Rods, Field: cod  
Foreign Key table:      Gitel,  Field: cod_rods
Это MS SQL. MySQL у меня в другом месте крутится. Тратить 2 часа на дорогу - не буду.

PM MAIL   Вверх
JavaCraft
Дата 3.5.2007, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



Спор не о чем.

Цитата(SergeBS @  3.5.2007,  09:13 Найти цитируемый пост)
БД без применения нормализации не бывает

При чем тут нормальные формы! Мы говорим не об организации данных, а о вполне конкретной декларации
ссылочной целостности. Вы спорите непонятно о чём. Похоже, что Вы не поняли вопроса.

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

Покажите мне код, который работает эффективнее с FK чем без них, при одинаковой организации данных, включая нормализацию и наличие индексов!

PM MAIL   Вверх
SergeBS
Дата 3.5.2007, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



JavaCraft, 
Цитата
При чем тут нормальные формы! Мы говорим не об организации данных, а о вполне конкретной декларации ссылочной целостности. Вы спорите непонятно о чём. Похоже, что Вы не поняли вопроса.

Я не спорю. Я констатирую факты. 
Факт №1: если нет справочников, то нет БД. Вытекает из нормализации.
Факт №2: если есть справочники, то есть FK. Вытекает из устройства серверов БД, точнее из ACID, что должно соблюдаться сервером. Все остальные "решения" - плоды буйной фантазии недоучек. Кончаются всегда плохо. 
И не надо декларировать "сферического коня в вакууме" и прочие "ссылочные целостности". Надо доки читать. И понимать.

Цитата
Покажите мне код, который работает эффективнее с FK чем без них, при одинаковой организации данных, включая нормализацию и наличие индексов!

Я не могу показать квадратное колесо. Т.е. код, работающий на БД без FK. Поскольку БД без FK не бывает.
PM MAIL   Вверх
JavaCraft
Дата 3.5.2007, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



Цитата(SergeBS @  3.5.2007,  12:13 Найти цитируемый пост)
JavaCraft, 

Цитата
При чем тут нормальные формы! Мы говорим не об организации данных, а о вполне конкретной декларации ссылочной целостности. Вы спорите непонятно о чём. Похоже, что Вы не поняли вопроса.

Я не спорю. Я констатирую факты. 
Факт №1: если нет справочников, то нет БД. Вытекает из нормализации.
Факт №2: если есть справочники, то есть FK. Вытекает из устройства серверов БД, точнее из ACID, что должно соблюдаться сервером. Все остальные "решения" - плоды буйной фантазии недоучек. Кончаются всегда плохо. 
И не надо декларировать "сферического коня в вакууме" и прочие "ссылочные целостности". Надо доки читать. И понимать.


Цитата
Покажите мне код, который работает эффективнее с FK чем без них, при одинаковой организации данных, включая нормализацию и наличие индексов!

Я не могу показать квадратное колесо. Т.е. код, работающий на БД без FK. Поскольку БД без FK не бывает. 


Сколько слюней и всё не по делу.
А судя по топику, что такое FK и БД ты вообще не знаешь.
PM MAIL   Вверх
SergeBS
Дата 3.5.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



Цитата
В приведенном коде нет и намека не только на декларацию Foreign Key, но и на ее конкретное применение в коде.

Если речь о МОЕМ примере, то повторю:
Цитата
FK_gitel_rods:
Primary Key Table:      Rods, Field: cod  
Foreign Key table:      Gitel,  Field: cod_rods

FK_gitel_rods - это Foreign Key для таблицы gitel. А в коде применять - ЭТО КАК? Сам-то понял, что сказал?

Добавлено через 5 минут и 33 секунды
JavaCraft, 
Знаешь, "знаток", ПРОЧТИ-ТАКИ ДОКИ. И не весели публику изобретательством. Пока я наблюдаю упорное старание подвести под БД то, что БД не является. Я привожу факты. А в ответ -  "а я не то имел в виду, да никто ничего не понял, кроме меня, самого умного и красивого".
PM MAIL   Вверх
JavaCraft
Дата 3.5.2007, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: 0
Всего: 1



Цитата(SergeBS @  3.5.2007,  09:13 Найти цитируемый пост)
FK_gitel_rods:
Primary Key Table:      Rods, Field: cod  
Foreign Key table:      Gitel,  Field: cod_rods


Это чё за хрень? Ты на MySQL напиши. Топик и раздел по MySQL. Куда смотрит модератор?
Цитата(SergeBS @  3.5.2007,  12:22 Найти цитируемый пост)
А в коде применять - ЭТО КАК? Сам-то понял, что сказал?

Я то понял, а ты нихрена не въезжаешь.
По русски написано. "Покажи код который эффективнее работает при наличии FK чем без них".

PM MAIL   Вверх
SergeBS
Дата 3.5.2007, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 2
Всего: 22



JavaCraft, 
Цитата
По русски написано. "Покажи код который эффективнее работает при наличии FK чем без них".

Еще раз:
Я не могу показать квадратное колесо. Т.е. код, работающий на БД без FK. Поскольку БД без FK не бывает. 

PM MAIL   Вверх
Бонифаций
Дата 3.5.2007, 14:31 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 827
Регистрация: 15.9.2005
Где: Brisbane

Репутация: 20
Всего: 40



Цитата(JavaCraft @ 20.4.2007,  17:50)
Разрабатываю базу данных с очень большим количеством таблиц на пределе возможностей мускула.
Теоретически, между всеми таблицами существует множество зависимостей
На этапе проектирования эти зависимости описываются внешними ключами.
Изменяемые таблицы InnoDB, не изменяемые MYISAM.
Таблицы генерируются в процессе работы приложения, большинство ключей тоже.

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

Достоинства внешних ключей:
1) Не обязательно следить за корректностью операций удаления или изменения записей.

Недостатки:
1)  В следствие необязательности контроля за корректностью операций удаления или изменения записей
 многие запросы будут обрабатываться впустую, расходуя ресурсы сервера, а исключительные события будут тормозить программу, как это имеет место при любой обработке исключений.

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

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

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

Что думает уважаемый All по этому поводу?

1) Для одновременного использования myisam и innodb требуются очень веские причины. Для нормальной работы myisam надо выделять хороший key_buffer, для innodb - солидный innodb_buffer_pool_size. Буферы, которые используются myisam и innodb не пересекаются между собой, каждый использует только свои. Это значит - при использовании только innodb можно выделить ему гораздо больше ресурсов. если вы используете и то и другое, каждый из них будет "голодать" (memory starving)  "на пределе возможностей" mysql

2) FK выполняются на гораздо более низком уровне чем хранимки. де-факто хранимки выполняются поверх уровня движков(innodb, myisam и тд), FK отрабатываются внутри engine, и во многих случаях вообще не лезет в таблицу (если страница индекса в кэше). Производительность FK выше чем хранимок. Если Вам нужны дополнительные проверки, их лучше делать в добавление к FK, не "вместо" них.

3) Не очень понятна идея хранить справочники в myisam а таблицы в innodb, и  на основании того, что myisam таблицы не изменяются, считать что FK им не нужны..  Innodb таблицы то меняются (и не только на insert/delete как вы везде пишете)  но и на update.  Справочники не меняются, но сылки то на них есть в основных таблицах. Без FK можете получить ссылки на отсутствующие/не те  записи в справочниках. Разумнее было бы все же все хранить в innodb, и использовать FK. Тем более что оттюненый innodb на больших нагрузках работает шустрее myisam.

4) " Высокое количество зависимостей непомерно визуально загромождает среду разработки, чем затрудняет проектирование." - честно говоря выглядит как юмор. 

5) "Если произойдет маловероятный но возможный системный сбой внешнего ключа, то поднять базу будет очень проблематично, может быть даже не поможет откат транзакции." Это что имеется в виду?  Приведите пример когда откат транзакции не поможет? В голову только приходит случай если часть таблиц в innodb а часть в myisam. Кстати SET UNIQUE_CHECKS=0; и SET FOREIGN_KEY_CHECKS=0; при восстановлении вполне спасут и в случае такой (очень гипотетической) ситуации. А вообще процедуры восстановления достаточно обкатаны в mysql.




--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0554 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.