Может ли SQLite поддерживать эту схему?

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

Я думал о столбце с именем ParentDepartmentID в качестве внешнего ключа для другого отдела. Если этот ключ равен нулю, это означает, что это родительский отдел высшего класса, а не дочерний по отношению к какому-либо другому отделу.

Я думаю, вы могли бы назвать это самоссылающимся идентификатором. Поддерживает ли SQLite это? Имея внешний ключ, но также допуская нули?

Как бы вы решили этот вариант использования?


person Community    schedule 31.10.2010    source источник


Ответы (2)


Почему бы и нет?

sqlite> create table selfref (id integer primary key, 
   name string, parent integer references selfref (id));
sqlite> .schema
CREATE TABLE selfref (id integer primary key, name string, 
   parent integer references selfref (id));
sqlite> insert into selfref values (null, "alice", null);
sqlite> insert into selfref values (null, "bob", null);
sqlite> insert into selfref values (null, "charlie", 
    (select id from selfref where name = "alice"));
sqlite> select * from selfref;
1|alice|
2|bob|
3|charlie|1
sqlite> 
person msw    schedule 31.10.2010

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

Однако проблема с моделью списка смежности заключается в том, что рекурсивные операции очень сложно написать, если только СУБД не может выполнять рекурсивные запросы.

Некоторые СУБД, такие как SQL Server 2005, Postgres 8.4 и Oracle 11g1, поддерживают рекурсивные запросы с общие табличные выражения с использованием ключевого слова WITH). Эта функция позволяет легко писать рекурсивные запросы, но sqlite и MySQL еще не поддерживают рекурсивные запросы.

Возможно, вам будет интересно ознакомиться со следующей статьей, в которой описывается альтернативная модель (модель вложенного множества< /em>), что значительно упрощает рекурсивные операции, несмотря на то, что модель вложенного набора определенно сложнее, чем список смежности:

Кроме того, я также предлагаю ознакомиться со следующей презентацией и сообщениями @Bill Karwin, постоянным участником Stack Overflow. 2:

Модель замыкающей таблицы, описанная в этих ссылках, является очень хорошей альтернативой модели вложенных наборов. Далее Билл описывает эту модель в своей книге SQL Antipatterns (выдержка из главы по этой теме [PDF]).

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


1 Oracle также может выполнять рекурсивные запросы, используя CONNECT BY, который поддерживается, начиная с версии 2.

2 Вы также можете ознакомиться со следующим сообщением о переполнении стека: Производительность рекурсивной обработки данных с использованием Java и SQLite, обсуждая эту тему.

person Daniel Vassallo    schedule 31.10.2010
comment
Вы меня опередили: P Вот страница о поддержке sqlite для внешнего ключа: sqlite.org/foreignkeys.html - person Endy Tjahjono; 31.10.2010
comment
Я думаю, что модель здесь более конкретно дерево. Список смежности используется для представления графов (какими, однако, являются деревья)... - person jetru; 31.10.2010