Рекурсивные иностранные ключи в sqlite - PullRequest
4 голосов
/ 29 июня 2011

Разрешены ли в sqlite собственные ссылочные или рекурсивные внешние ключи?Есть ли специальный синтаксис для этого?До сих пор я пробовал следующее безрезультатно: FOREIGN KEY(ParentPrimaryKeyId) REFERENCES ThisTableName(PrimaryKeyId)

Для справки, я ориентируюсь на sqlite 3.6.22 в iOS 4.

Ответы [ 2 ]

9 голосов
/ 29 июня 2011

Да, sqlite поддерживает внешние ссылки, ссылающиеся на себя, например:

sqlite> PRAGMA foreign_keys = ON;
sqlite> CREATE TABLE SomeTable (
   ...>     id INTEGER PRIMARY KEY AUTOINCREMENT,
   ...>     parent_id INTEGER, 
   ...>     FOREIGN KEY(parent_id) REFERENCES SomeTable(id));
sqlite> INSERT INTO SomeTable (parent_id) VALUES (234324);
Error: foreign key constraint failed
sqlite> INSERT INTO SomeTable (parent_id) VALUES (NULL);
sqlite> SELECT * FROM SomeTable;
1|
sqlite> INSERT INTO SomeTable (parent_id) VALUES (1);
sqlite> SELECT * FROM SomeTable;
1|
2|1
sqlite> 
0 голосов
/ 29 июня 2011

SQLite поддерживает внешние ключи, в которых ссылочная таблица и ссылочная таблица являются одной и той же таблицей. (См., Например, ответ Sixfeetsix. Целевой столбец ограничения внешнего ключа должен иметь ограничение «первичный ключ» или «уникальный»). Но вам следует задуматься о том, нужно ли вам хранить информацию о вещах и отношения между вещами в одной таблице.

Например, для "родителей" и "детей" что-то в этом роде часто является лучшей идеей.

pragma foreign_keys = on;
create table persons (
  person_id integer primary key,
  person_name varchar(15) not null
);
insert into persons values (1, 'Dad');
insert into persons values (2, 'One son');
insert into persons values (3, 'One daughter');
create table persons_children (
  parent_id integer references persons (person_id),
  child_id integer references persons (person_id),
  check (parent_id <> child_id),
  primary key (parent_id, child_id)
);
insert into persons_children values (1,2);
insert into persons_children values (1,3);

Информация о лицах в одной таблице; информация об их отношениях в другом. Затем получите имена по

select pc.parent_id, p1.person_name as parent_name,
       pc.child_id,  p2.person_name as child_name
from persons_children pc
inner join persons p1 on (p1.person_id = pc.parent_id)
inner join persons p2 on (p2.person_id = pc.child_id);

1  Dad  2  One son
1  Dad  3  One daughter

SQLite не поддерживает рекурсивные запросы в том смысле, как, скажем, PostgreSQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...