Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.02.25;
Скачать: [xml.tar.bz2];

Вниз

Один к одному   Найти похожие ветки 

 
Гоблин   (2006-11-15 21:22) [0]

Привет

Собственно, как реализовать сабж? Про один ко многим всё понятно, а про сабж никак не могу найти.


 
Desdechado ©   (2006-11-15 21:32) [1]

Обычно это не нужно. Но если очень хочется, то в первой таблице PK, во второй FK на него + по этому же полю UNIQUE


 
Anatoly Podgoretsky ©   (2006-11-15 21:37) [2]

> Гоблин  (15.11.2006 21:22:00)  [0]

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


 
atruhin ©   (2006-11-16 03:52) [3]

Ну почему это не нужно? Обычное наследование таблиц.
Пример:
таблица КОРРЕСПОНДЕНТЫ
           ФИЗ.ЛИЦА
           ЮР. ЛИЦА

Корреспонденты содержит общие поля, на нее FK от документов,
остальные детализация.
У нас вся система на подобном наследовании построенна.


 
ЮЮ ©   (2006-11-16 04:14) [4]


> то в первой таблице PK, во второй FK на него + по этому
> же полю UNIQUE



А почему не просто, во второй PK и FK на PK в первой ?


 
Desdechado ©   (2006-11-16 09:40) [5]

ЮЮ ©   (16.11.06 04:14) [4]
Сути это не меняет (если FK и PK в подчиненной таблице по той же самой комбинаци полей), однако в случае 1:1 мне "ближе и понятнее" все-таки UQ. Оно точнее отображает смысл, т.к. PK претендует на ведущую роль, а таблица все-таки подчиненная.


 
ЮЮ ©   (2006-11-16 09:44) [6]


> PK претендует на ведущую роль, а таблица все-таки подчиненная.

FK вполне умерит эти претензии :)


 
Anatoly Podgoretsky ©   (2006-11-16 10:29) [7]

> ЮЮ  (16.11.2006 09:44:06)  [6]

Но ПК может их расширить


 
Гоблин   (2006-11-16 21:11) [8]

Так что же лучше
FK+Union
или
PK?


 
Гоблин   (2006-11-16 21:12) [9]

Ой, что я написал?

UNIQUE


 
Desdechado ©   (2006-11-16 21:18) [10]

Если ты внимательно читаешь, то заметишь, что разговоры шли о PK vs UQ. FK в любом случае нужен.


 
Гоблин   (2006-11-16 22:23) [11]

А, ну понятно. Но что же лучше?


 
atruhin ©   (2006-11-17 04:29) [12]

Да что угодно, обычный холивар, типа Delphi vs C++


 
Гоблин   (2006-11-18 14:04) [13]

Ну ладно тогда, сэнкс.


 
Гоблин   (2006-11-18 17:58) [14]

Хм.

А я вот тут подумал. Что мне будет мешать вставить запись в системную таблицу без вставки соответствующей записи в подчинённую? То же самое с удалением.


 
Desdechado ©   (2006-11-18 20:19) [15]

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

ЗЫ кстати, есть еще OUTER JOIN, который позволяет в некоторых случаях не сильно заботиться о наличии записей в подчиненной таблице


 
Гоблин   (2006-11-18 20:48) [16]

В случае одной таблицы not null там, где это надо.


 
atruhin ©   (2006-11-18 20:59) [17]

> В случае одной таблицы not null там, где это надо.

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


 
Гоблин   (2006-11-21 22:09) [18]

А вот в случае IB\FB в таких таблицах можно использовать один генератор на все таблицы или по отдельности? Или в системной таблице вообще на пологаться на автоинкремент, а брать ID из справочников?


 
atruhin ©   (2006-11-22 12:14) [19]

> Или в системной таблице вообще на пологаться на автоинкремент,
> а брать ID из справочников?

ничего не понятно


 
Desdechado ©   (2006-11-22 12:22) [20]

> А вот в случае IB\FB в таких таблицах можно использовать один генератор на все таблицы или по отдельности?
Без разницы. Но я предпочитаю каждой таблице по генератору (если в ней есть, чего нумеровать).


 
Гоблин   (2006-11-22 19:25) [21]

Ай, извиняюсь. Въехал.

Последний вопрос. Вставку записей сразу в две таблицы с FK между ними нельзя сразу сделать? Либо два запроса, либо через ХП. Я не прав?


> Desdechado ©   (18.11.06 20:19) [15]
> Это уже задача триггера.

А можно пример такого триггера? А то моя идея проверять все поля на предмет вставки мне что-то не нравится.


 
Desdechado ©   (2006-11-22 20:30) [22]

> Последний вопрос.
Операции строго последовательные, хоть сами по себе, хоть в ХП.

> пример такого триггера
например, в after insert-триггере на главную таблицу делать insert в подчиненную сразу


 
MsGuns ©   (2006-11-22 20:39) [23]

>Гоблин   (22.11.06 19:25) [21]
>Последний вопрос. Вставку записей сразу в две таблицы с FK между ними нельзя сразу сделать?

Можно. Для этого и существуют транзакции

>Либо два запроса, либо через ХП. Я не прав?

Для сервера в сущности все едино: выполняются ли две вставки в таблицы (или таблицу) двумя клиентскими запросами или в контексте одного скрипта (хранимки) двумя шагами, оформленными каждый как запрос.
Главное - все существующие стандарты сиквеля  не позволяют в одном SQL-операторе вносить изменения более чем в одну таблицу (И ЭТО ПРАВИЛЬНО !!!)


 
Гоблин   (2006-11-22 21:06) [24]

Т.е. этот триггер должен вставить не важно что в подчинённую таблицу - лишь бы вставил. Но как узнать ID текущей записи в главной таблице и передать в триггер? Можно ли для этого использовать значение генератора?

А как же быть с удалением? Я ж могу что-то удалить из справочника, а главная об этом ничего знать не будет.


 
Desdechado ©   (2006-11-22 21:17) [25]

У тебя каша в голове.
Справочник, этота таблица, НА которую ссылаются. Она же MASTER-таблица или главная.
Поэтому при удалении из главной в зависимости от того, как ты опишешь внешний ключ в подчиненной таблице,так и будет себя вести. Если с ON DELETE CASCADE, то удалятся записи и в подчиненной тоже. Если без CASCADE, то будет ошибка - надо сначала удалять записи из подчиненной, потом из главной.
Если же боишься удаления из подчиненной напрямую, напиши процедуру удаления, которая будет удалять сразу из двух таблиц. И дай процедуре право на удаление из этих таблиц. А у юзера отними права на удаление из этих таблиц напрямую.

> как узнать ID текущей записи в главной таблице и передать в триггер
В триггере и так доступны все поля строки той таблицы, на которую он сработал. Читай LangRef.pdf


 
Гоблин   (2006-11-23 20:03) [26]


> В триггере и так доступны все поля строки той таблицы, на
> которую он сработал. Читай LangRef.pdf


Это случаем не OLD и NEW?


 
atruhin ©   (2006-11-24 06:22) [27]

Да, они


 
Гоблин   (2006-11-24 17:44) [28]

А как бы тогда значение ID на клиента переслать?


 
Гоблин   (2006-11-25 19:17) [29]

А вот такая хранимка будет работать или нет


CREATE TABLE CATALOG
(
 ID INTEGER NOT NULL,
 Name   VARCHAR(50) CHARACTER SET WIN1251 NOT NULL,
 Object_type SMALLINT NOT NULL,
PRIMARY KEY (ID)
);

CREATE TABLE TREE
(
 ID INTEGER NOT NULL,
 Sys_ID INTEGER NOT NULL,
 SysParent_ID  INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT RTREE FOREIGN KEY (Sys_ID) REFERENCES CATALOG (ID),
CONSTRAINT RTREEPARENTSYS FOREIGN KEY (SysParent_ID) CATALOG (ID)
);

CREATE PROCEDURE SETNAMES (parent_ID INTEGER, Name_ Varchar(20), Table SMALLINT)
RETURNS (DID INTEGER)
AS
BEGIN
SET TRANSACTION;
INSERT INTO CATALOG (Name, Object_type) VALUES ("(dummy)", :Table);
SELECT C.ID FROM CATALOG C WHERE C.Name = "(dummy)" INTO :DID;
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:DID, :parent_ID);
UPDATE CATALOG SET Name = :Name_ WHERE ID = :DID;
COMMIT;
END


 
atruhin ©   (2006-11-25 20:18) [30]

> А вот такая хранимка будет работать или нет

SET TRANSACTION;,COMMIT; - лишнии, вроде даже не скомпилируется, но
в любом случае, управлять транзакциями в процедурах нельзя.
Вообще должно быть примерно так:

CID = gen_id(GEN_CATALOG_ID, 1);
INSERT INTO CATALOG (ID, Name, Object_type) VALUES (:CID, :NAME_, :Table);
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:CID, :parent_ID);


 
atruhin ©   (2006-11-25 20:20) [31]

А еще лучше сходить на www.ibase.ru
Там прочитать ВСЕ статьи, в них найдешь ответы на все твои вопросы.


 
Гоблин   (2006-11-25 21:19) [32]

А, т.е. процедуру запускать в контексте транзакции с клиента?
С ibase.ru выкачал всё, что можно, и что нельзя.
Для FB 2.0 проще, наверное, будет так

CREATE PROCEDURE SETNAMES (parent_ID INTEGER, Name_ Varchar(20), Table SMALLINT)
RETURNS (DID INTEGER)
AS
BEGIN
INSERT INTO CATALOG (Name, Object_type) VALUES (:Name_, :Table) RETURNING ID INTO :DID;
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:DID, :parent_ID);
END


А инкремент ID через триггер.


 
MsGuns ©   (2006-11-25 23:15) [33]

>atruhin ©   (25.11.06 20:18) [30]
>но в любом случае, управлять транзакциями в процедурах нельзя.

Вы уверены в этом ?


 
atruhin ©   (2006-11-26 00:52) [34]

> Вы уверены в этом ?

Ну с поправкой, что мы говорим о FB, то уверен.


 
Гоблин   (2006-11-30 20:16) [35]

Ну ладно, ещё раз спасибо.
Всех целую.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2007.02.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.059 c
2-1170676945
Alex_ey
2007-02-05 15:02
2007.02.25
treeview


15-1170170111
Самовар
2007-01-30 18:15
2007.02.25
Опять ДНС :-((


4-1160766541
gellmar
2006-10-13 23:09
2007.02.25
Как реализовать парсинг PE64 файлов под win32 на делфи?


15-1170016567
i-am-vladko
2007-01-28 23:36
2007.02.25
Assembler


2-1170852064
Лебедев
2007-02-07 15:41
2007.02.25
memo





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский