Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Вопрос по SQL Server 2000 и foreign key

210  1 2 все
krys посетитель16.01.07 15:11
NEW 16.01.07 15:11 
Последний раз изменено 16.01.07 15:12 (krys)
привет. У меня такой вопрос.
Есть две таблицы. Обе таблицы хранят данные описываюсчие графический обьект определенного типа. Причем 1 Таблица содержит уникальный номер фигуры и текстовое обозначение на чертеже. Другая Таблица хранит данные о свойствах фигуры таких как (к примеру) цвет, размер и т.д. Также в этой таблице содержится как foreign key Уникальный номер фигуры.
Сейчас возникла необходимость для фигуры другого типа иметь отдельную таблицу для свойств, аналогичную выше описанной.
Поскольку структуры новой и старой таблицы полностью совпадают,можно использовать уже имеющуюся таблицу.
Проблема в foreign key :
Сейчас foreign key позволяет мне автоматически(каскадом) стирать и обновлять данные в таблице где храняться данные о свойствах Фигуры.
Если я подключу еще одну таблицу к таблице для хранения свойств Фигур, то я должен буду убрать связи по foreign key .
Как можно сделать что бы эффект каскада при стирании и обновлении данных даных все же сохранялся?
Можно ли для этого использовать триггеры?
P.S. Работаю с Microsoft SQL Server 2000
стойте там и слушайте сюда, именно отсюда будет проистекать
#1 
  digital.pilot старожил16.01.07 15:21
digital.pilot
NEW 16.01.07 15:21 
в ответ krys 16.01.07 15:11, Последний раз изменено 16.01.07 15:23 (digital.pilot)

не совсем понятно, почему FK придется убрать, выложи скрипты таблиц?
В ответ на:
Можно ли для этого использовать триггеры?

конечно. AFTER DELETE на таблицу с PK.
#2 
Murr коренной житель16.01.07 15:38
Murr
NEW 16.01.07 15:38 
в ответ krys 16.01.07 15:11
Как можно сделать что бы эффект каскада при стирании и обновлении данных даных все же сохранялся?
------
Указать, что разрешено каскадное удаление. Но надо смотреть, чтобы структура позволяла выполнить это удаление.
Можно ли для этого использовать триггеры?
-----
Да, но это избыточно для простого каскадного удаления.
#3 
krys посетитель16.01.07 16:06
NEW 16.01.07 16:06 
в ответ digital.pilot 16.01.07 15:21
--
-- Structure for table Function :
--
CREATE TABLE [dbo].[Function] (
[FunctionID] nvarchar(50) COLLATE Latin1_General_CI_AS NOT NULL,
[Function] nvarchar(255) COLLATE Latin1_General_CI_AS,
[Check] nvarchar(50) COLLATE Latin1_General_CI_AS
)
ON [PRIMARY]
GO
--
-- Structure for table FunctionProp :
--
CREATE TABLE [dbo].[FunctionProp] (
[Id] int IDENTITY(1, 1) NOT NULL,
[FunctionId] nvarchar(50) COLLATE Latin1_General_CI_AS,
[Label] nvarchar(255) COLLATE Latin1_General_CI_AS,
[Property] nvarchar(80) COLLATE Latin1_General_CI_AS,
[Value] nvarchar(255) COLLATE Latin1_General_CI_AS,
[SortKey] nvarchar(50) COLLATE Latin1_General_CI_AS,
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[FunctionProp]
ADD CONSTRAINT [FK_FunctionProp_Function] FOREIGN KEY ([FunctionId])
REFERENCES [dbo].[Function] ([FunctionID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
-- Structure for table FunctionGroup :
--
CREATE TABLE [dbo].[FunctionGroup] (
[FunctionGroupID] nvarchar(50) COLLATE Latin1_General_CI_AS NOT NULL,
[FunctionGroup] nvarchar(50) COLLATE Latin1_General_CI_AS,
[Facility] nvarchar(50) COLLATE Latin1_General_CI_AS,
[FileName] nvarchar(255) COLLATE Latin1_General_CI_AS,
[Check] nvarchar(50) COLLATE Latin1_General_CI_AS
)
ON [PRIMARY]
GO
ON [PRIMARY]
GO
ALTER TABLE [dbo].[Function]
ADD CONSTRAINT [PK_Function]
PRIMARY KEY CLUSTERED ([FunctionID])
ON [PRIMARY]
GO
ALTER TABLE [dbo].[FunctionGroup]
ADD CONSTRAINT [PK_FunctionGroup]
PRIMARY KEY CLUSTERED ([FunctionGroupID])
ON [PRIMARY]
GO
ALTER TABLE [dbo].[FunctionProp]
ADD CONSTRAINT [PK_FunctionProp]
PRIMARY KEY CLUSTERED ([Id])
ON [PRIMARY]
GO
надеюсь что из кода видно, что существует связь между таблицей Function и FunctionProp.
Если я аналогично через Foreign Key свяжу FunctionGroup.FunctionGroupID и FunctinProp.FunctionID (и в том и в другом случае ето уникальный ключ) то при попытке внести новое значение в FunctionProp vозникает ошибка, поскольку если ID существует в таблице Function оно не существует в FunctionGroup и наоборот.
стойте там и слушайте сюда, именно отсюда будет проистекать
#4 
toptop знакомое лицо18.01.07 10:20
NEW 18.01.07 10:20 
в ответ krys 16.01.07 16:06
Т.е. если несколько перефразировать вопрос:
Можно ли создать одну подчиненную таблицу с двумя главными?
Это когда думаешь: одна голова - хорошо, а две лучше. А начальник должен быть все же один: у двух нянек - таблица без ключа.
Если уж так невмоготу, то добавь недостающие до FunctionGroup поля в Function и пользуйся одной главной и одной подчненной таблицей.
А лучше сделать FunctionGroupProp: окорочка к окорочкам, а раковые шейки - отдельно.
#5 
  scorpi_ скептик18.01.07 13:50
NEW 18.01.07 13:50 
в ответ toptop 18.01.07 10:20
Можно просто добавить FunctionGroupID в FunctionProp.
#6 
toptop знакомое лицо19.01.07 13:49
NEW 19.01.07 13:49 
в ответ scorpi_ 18.01.07 13:50
Это как же надо ненавидеть базы данных, чтобы такое придумать.
По всем рекомандациям на связные столбцы подчиненной таблицы должны быть проиндексированы. А как же бедняжка там искать будет, если там половина NULL торчать будет. А без индекса скучно за join-ами наблюдать будет.
#7 
Murr коренной житель19.01.07 14:03
Murr
NEW 19.01.07 14:03 
в ответ toptop 19.01.07 13:49
Это как же надо ненавидеть базы данных, чтобы такое придумать.
------
Годике этак в 2001-м я выкладывал настоящий шедевр под названием "Ужас ДБА".
Причем этот "Ужас ДБА" полностью соответствовал описанию той задачи, над
которой я тогда трудился... там было с десяток таблиц, каждая из которых имела
девять остальный в качестве Мастер-таблиц... Надо будет найти ту картинку...
#8 
krys посетитель19.01.07 15:32
NEW 19.01.07 15:32 
в ответ toptop 18.01.07 10:20
именно об этом и идет речь:
создать одну подчиненную таблицу с двумя главными
Я и сделал отдельную подчиненную таблицу, но шефа это не устраивает: обе подчиненных таблицы имеют одинаковую структуру: Отличие только в названии столбцов
[FunctionID] и [FunctionGroupID] (суть таже)
стойте там и слушайте сюда, именно отсюда будет проистекать
#9 
toptop знакомое лицо19.01.07 15:52
NEW 19.01.07 15:52 
в ответ krys 19.01.07 15:32
Тогда воспользуйся советом scorpi_ и будет шефу счастье. Только предупреди, что возможно тормозить будет при работе.
#10 
toptop знакомое лицо19.01.07 15:56
NEW 19.01.07 15:56 
в ответ Murr 19.01.07 14:03
А индекс на bool - поле видеть не доводилось? УЖОС!
#11 
krys посетитель19.01.07 16:34
NEW 19.01.07 16:34 
в ответ toptop 19.01.07 15:52
А если все таки тригерры для главных таблиц для реагирования на стрирание и обновление строчек примерно такого содержания?
CREATE TRIGGER [Update_FunctionProps] ON [dbo].[Functions]
FOR UPDATE
AS
DECLARE @orig_id nvarchar(50), @new_id nvarchar (50)
SELECT @orig_id= FunctionID from deleted
SELECT @new_id = FunctionID from inserted
if( @orig_id<>@new_id)
BEGIN
UPDATE FunctionProperties
SET FunctionProperties.FunctionID= @new_id
where FunctionID IN(select FunctionID from deleted)
END
CREATE TRIGGER [DELETE_ID] ON [dbo].[Functions]
FOR DELETE
AS
DELETE
FROM [FunctionProperties]
where [FunctionProperties].FunctionID IN (SELECT FunctionID FROM Deleted)
стойте там и слушайте сюда, именно отсюда будет проистекать
#12 
Murr коренной житель19.01.07 18:17
Murr
NEW 19.01.07 18:17 
в ответ toptop 19.01.07 15:56
Индекс - куда не шло - вот вместо индекса разбитие на четыре таблицы - это таки и есть "УжосНах"...
#13 
Murr коренной житель19.01.07 18:24
Murr
NEW 19.01.07 18:24 
в ответ krys 19.01.07 16:34
Тут попутный вопросик возник - у тебя _ключи_ формата NVARCHAR(50) - это какое-то специальное извращение или просто используется что-то введенное пользователем? (шутю)
#14 
  scorpi_ скептик19.01.07 23:18
19.01.07 23:18 
в ответ toptop 19.01.07 13:49
В ответ на:
А как же бедняжка там искать будет, если там половина NULL торчать будет. А без индекса скучно за join-ами наблюдать будет.

Индекс будет работать совершенно нормально. Мне кажется, ты не вполне понимаешь, как они имплементируются, и какая у них временная сложность.
#15 
toptop знакомое лицо20.01.07 22:47
NEW 20.01.07 22:47 
в ответ scorpi_ 19.01.07 23:18
В ответ на:
Мне кажется, ты не вполне понимаешь, как они имплементируются, и какая у них временная сложность.

Я имею ввиду то, что при индексировании столбца наполовину заполненного NULL значениями, таблица индекса будет содержать эти значения, ввиду чего она будет раздута, а пользы от этого - пшик и поиск по этому столбцу за счет индекса не обязательно будет быстрее, чем с индексом.
#16 
toptop знакомое лицо20.01.07 22:50
NEW 20.01.07 22:50 
в ответ krys 19.01.07 16:34
В данном случае я бы назвал это программирование для программирования. В MS SQL есть стандартные On delete Cascade и On Update Cascade. Не думаю, что trigger будет работать быстрее.
#17 
toptop знакомое лицо20.01.07 22:57
NEW 20.01.07 22:57 
в ответ Murr 19.01.07 18:17, Последний раз изменено 20.01.07 22:58 (toptop)
Огульно не могу ни поддержать, ни опровергнуть. Принцип разделяй и властвуй еще никто не отменял.
Например, таблица заказов: активные и архив. Почему бы их не разделить, если в повседневке мне только с активными работать, а в архив может вообще никто не заглянет?
Хотя 4, наверное, все же многовато.
#18 
Murr коренной житель21.01.07 00:28
Murr
NEW 21.01.07 00:28 
в ответ toptop 20.01.07 22:57
Хотя 4, наверное, все же многовато.
-------
труеб фалсе, нулл, еррерс...
#19 
  scorpi_ коренной житель21.01.07 01:13
NEW 21.01.07 01:13 
в ответ toptop 20.01.07 22:47
В ответ на:
Я имею ввиду то, что при индексировании столбца наполовину заполненного NULL значениями, таблица индекса будет содержать эти значения, ввиду чего она будет раздута, а пользы от этого - пшик и поиск по этому столбцу за счет индекса не обязательно будет быстрее, чем с индексом.

Во-первых, это не таблица. Это обычно дерево, чаще всего B-Tree. А в нём как известно увеличение количества записей вдвое увеличивает время доступа на константную величину. Грубо говоря на одно сравнение. Во-вторых вовсе не факт, что некая конкретная имплементация индекса вообще сохраняет нулевые значения в индексе. Ибо нулевое значение по определению не равно никакому другому.
#20 
1 2 все