2009-07-24 4 views
6

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

Скажите, что у моей базы данных следующие таблицы; Клиентов Supplers SalesInvoices PurchaseInvoices Валюты

и т.д. и т.п.

Я хотел бы иметь возможность добавить «Notes» запись к любому типу записи

Нота таблица хотел бы этот

NoteID  Int (PK) 
NoteFK  Int 
NoteFKType Varchar(3) 
NoteText  varchar(100) 
NoteDate  Datetime 

Где NoteFK - это ПК клиента или поставщика и т. Д., А NoteFKType говорит, какой тип reco rd примечание против

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

Итак, как бы вы разработали вышеуказанное? Примечания FK должно быть в любом из приведенных выше таблиц

Cheers, Daniel

+0

Требуется ли ссылочная целостность на уровне базы данных, или вы можете жить с ссылочной целостностью, управляемой приложениями? – tschaible

ответ

-2

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

+1

Что делать, если он хочет иметь отношения «один ко многим»? Многие заметки для одного объекта.Он закончил бы со многими дополнительными таблицами, которые не требуются. – maciejkow

+1

Это не гарантирует, что один и тот же NoteID не ссылается более одного раза. Но это зависит от требований бизнеса. –

+0

Если есть потребность в одном-на-одном, мы можем хранить сохраненные запятыми notesIDs (это только обходное решение) вместо того, чтобы иметь разные таблицы для соединения. –

0

Вы можете добавить поле GUID в таблицы Customers, Suppliers и др. Затем в таблице «Примечания» измените внешний ключ, чтобы ссылаться на этот GUID.

Это не помогает целостности данных. Но это делает отношения M-to-N легко доступными для любого количества таблиц, и это избавляет вас от необходимости определять столбец NoteFKType в таблице Notes.

2

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

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

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

3

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

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

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

Что касается аргумента этой таблицы, которая становится слишком большой, то разбиение ее на пять таблиц сократит таблицу до примерно пятой части ее размера, но это не будет иметь никакого значения для доступа на основе индексов. Базы данных построены для обработки больших таблиц (при условии их правильной индексации).

0

Вы можете легко реализовать ключ «multi» -foreign с триггерами. Триггеры предоставят вам очень гибкий механизм, и вы сможете выполнить любые проверки целостности.

1

Я бы дважды подумал, прежде чем делать то, что вы предлагаете. В краткосрочной перспективе это может показаться простым и элегантным, но если вы действительно заинтересованы в целостности данных и производительности, то есть возможность иметь отдельные таблицы заметок для каждой родительской таблицы. На протяжении многих лет я подошел к этой проблеме, используя решения, найденные в других ответах (триггеры, GUID и т. Д.). Я пришел к выводу, что добавленная сложность и потеря производительности не стоят того. Имея отдельные таблицы заметок для каждой родительской таблицы, с соответствующими ограничениями внешнего ключа, поисковые запросы и объединения будут простыми и быстрыми. При объединении связанных элементов в одну таблицу синтаксис соединения становится уродливым, а таблица заметок будет огромным и медленным.

+0

+1 Я согласен и могу поручиться за это. В конечном итоге вы только усложняете свое решение и добавляете технический долг, который в конечном итоге придется решать. –

+0

С другой стороны, он может со своим текущим решением запускать запросы по всем нотам, что было бы сложно с несколькими таблицами заметок. – Thilo

+1

@Thilo - С учетом рекомендаций Майкла SQL View является более подходящим способом для объединения всех таблиц заметок в один источник запроса. –

1

Я согласен с Майклом Мак-Лоски в определенной степени.

Вопрос на мой взгляд: какова техническая стоимость наличия нескольких таблиц заметок?

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

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


На самом деле ответить на ваш вопрос ...

вариант Я хотел бы использовать это ограничение проверки с использованием User Defined Функция для проверки значений. Это работает в M $ SQL Server ...

CREATE TABLE Test_Table_1 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_2 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_3 (fk_id INT, table_name VARCHAR(64)) 
GO 

CREATE FUNCTION id_exists (@id INT, @table_name VARCHAR(64)) 
RETURNS INT 
AS 
BEGIN 
    IF (@table_name = 'Test_Table_1') 
     IF EXISTS(SELECT * FROM Test_Table_1 WHERE id = @id) 
      RETURN 1 
    ELSE 
    IF (@table_name = 'Test_Table_2') 
     IF EXISTS(SELECT * FROM Test_Table_2 WHERE id = @id) 
      RETURN 1 

    RETURN 0 
END 
GO 

ALTER TABLE Test_Table_3 WITH CHECK ADD CONSTRAINT 
    CK_Test_Table_3 CHECK ((dbo.id_exists(fk_id,table_name)=(1))) 
GO 
ALTER TABLE [dbo].[Test_Table_3] CHECK CONSTRAINT [CK_Test_Table_3] 
GO 

INSERT INTO Test_Table_1 SELECT 1 
GO 
INSERT INTO Test_Table_1 SELECT 2 
GO 
INSERT INTO Test_Table_1 SELECT 3 
GO 
INSERT INTO Test_Table_2 SELECT 1 
GO 
INSERT INTO Test_Table_2 SELECT 2 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_1' 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_2' 
GO 

В этом примере окончательная инструкция вставки не удалась.

1

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

create table Notes (
    id int PRIMARY KEY, 
    note varchar (whatever), 
    customer_id int NULL REFERENCES Customer (id), 
    product_id int NULL REFERENCES Product (id) 
) 

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

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

Для этой конструкции потребуется добавить новый столбец в Notes, если вы хотите добавить другую таблицу ссылок.

+0

Это, наверное, самое изящное решение. – Thilo

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