личные таблицы ссылок, хорошие или плохие? [закрыто]

Представляя географические местоположения в приложении, дизайн базовой модели данных предлагает два четких варианта (или, может быть, больше?).

Одна таблица с самоназывающим столбцом parent_id uk - london (london parent id = UK id)

или две таблицы с отношением от одного до нескольких с использованием внешнего ключа.

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

В общем, люди отклоняются от собственных ссылок на таблицы, или они A-OK?

31 голос | спросил NimChimpsky 30 52012vEurope/Moscow11bEurope/MoscowFri, 30 Nov 2012 17:08:06 +0400 2012, 17:08:06

3 ответа


36

Ничего плохого в таблицах саморегуляции.

Это общий шаблон проектирования базы данных для глубоких (бесконечных?) вложенных иерархий.

ответил Oded 30 52012vEurope/Moscow11bEurope/MoscowFri, 30 Nov 2012 17:26:06 +0400 2012, 17:26:06
3

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

Давайте сделаем пример:
У нас есть таблица отчетов,
и отчет может иметь родителя (menupoint, например, категория),
и этот родитель может сам иметь родителя (например, центр прибыли),
и т. д. до бесконечности.

Самый простой пример стандартного рекурсивного отношения, как и к любой самореферентной сущности /иерархии.

В результате получается таблица SQL-Server:

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'dbo.FK_T_FMS_Reports_T_FMS_Reports') AND parent_object_id = OBJECT_ID(N'dbo.T_FMS_Reports'))
ALTER TABLE dbo.T_FMS_Reports DROP CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.T_FMS_Reports') AND type in (N'U'))
DROP TABLE dbo.T_FMS_Reports 
GO



CREATE TABLE dbo.T_FMS_Reports 
( 
     RE_UID uniqueidentifier NOT NULL 
    ,RE_RE_UID uniqueidentifier NULL 
    ,RE_Text nvarchar(255) NULL 
    ,RE_Link nvarchar(400) NULL 
    ,RE_Sort int NOT NULL 
    ,RE_Status int NOT NULL 
    ,PRIMARY KEY CLUSTERED ( RE_UID ) 
); 

GO

ALTER TABLE dbo.T_FMS_Reports  WITH CHECK ADD  CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports FOREIGN KEY(RE_RE_UID) 
REFERENCES dbo.T_FMS_Reports (RE_UID) 
-- ON DELETE CASCADE -- here, MS-SQL has a problem 
GO

ALTER TABLE dbo.T_FMS_Reports CHECK CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports 
GO

Но у вас возникает проблема:
Когда вам нужно удалить menupoint со всеми его подменю, вы НЕ МОЖЕТ установить каскад delete-cascade, потому что Microsoft SQL-Server не поддерживает рекурсивные каскадные удаления (с другой стороны , PostGreSQL делает, в то время как MySQL не любит такую ​​структуру таблиц вообще, потому что она не поддерживает рекурсивные CTE).

Таким образом, вы можете взорвать целостность /функциональность с ним, что делает его обязательным для реализации таких функций в вашем собственном коде или в хранимой процедуре (если ваша СУРБД поддерживает хранимые процедуры).

Это, без сомнения, приведет к взрыву любого типа полностью автоматических динамических данных импорта /экспорта, потому что вы не можете просто запустить инструкцию delete для всех таблиц в соответствии с отношениями внешних ключей (не связанные с самим ссылкой), а также не можете простой select * и создать вставку для каждой строки в произвольном порядке.

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

Однако в правильных системах управления базами данных (например, PostgreSQL) с надлежащей оснасткой это не должно быть проблемой. Просто объясните, что только потому, что вы много платите за свои РСУБД (я смотрю на вас, Microsoft, Oracle =?) И /или на его ремень для инструментов, это не значит, что он запрограммирован правильно. И ни OpenSource (например, MySQL) не заставляет вас застраховаться от таких замечательных мелочей.

Дьявол в деталях, как говорится в старой поговорке.

Теперь не то, чтобы вы не могли решить такие проблемы, но я бы не рекомендовал его, если ваша система будет сложной (например, 200+ таблиц).
Плюс, в обычной коммерческой обстановке (как показано Дилбертом), вам просто не дадут этого времени.

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

ответил Quandary 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 15 Sep 2015 11:47:00 +0300 2015, 11:47:00
1

Хорошо, если отношения на самом деле иерархичны, а не сетевые отношения (например, Билль материалов - это сетевое отношение, а не иерархическое).

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

http://karwin.blogspot.ca/2010/03 /рендеринг деревьев-с-закрытия-tables.html

ответил Neil McGuigan 29 J0000006Europe/Moscow 2013, 23:41:51

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132