在SQL Server中设计邻接列表或父子关系?

时间:2015-12-15 00:33:03

标签: sql sql-server sql-server-2008 database-design

我正在尝试维护子引用ID及其父引用ID。我想用他们的父引号id存储两个子引用,所以我将能够查询哪个引用是父子关系。

我对设计感到困惑,如果我将第一个parent_id保持为NULL,则意味着如果子项本身是父项,则员工是经理或保留父项引号ID与子引用ID相同。

我使用NULL进行了两次设计,并使用相同的子引号id作为父引号id。

这将使我的设计更简单,更容易查询。

create table quotelist
(
  pk_aquotelistid int primary key identity(1,1),
  quoteid int,
  parent_quoteid int
);

insert into quotelist values(1,1), (2,1),(3,1);
insert into quotelist values(4,4), (5,4);
insert into quotelist values(6,6), (7,4);

http://www.frostjedi.com/phpbb3/viewtopic.php?f=46&t=19553

OR

create table quotelist
(
  pk_aquotelistid int primary key identity(1,1),
  quoteid int,
  parent_quoteid int
);

insert into quotelist values(1,NULL), (2,1),(3,1);
insert into quotelist values(4,NULL), (5,4);
insert into quotelist values(6,NULL), (7,4);

http://sqlfiddle.com/#!3/c4ad9/1

2 个答案:

答案 0 :(得分:0)

我认为在parent_quoteid中使用NULL是更自然的方式,没有人必须记住在每个查询中添加quoteid != parent_quoteid,以排除没有parent_quote_id的记录。

此外,一旦parent_quoteid为NULL,就不需要在表中插入这样的记录。这些记录可以使用LEFT JOIN的引用表获得,其中quote.quoteid = quotelist.parent_quoteid上的quotelist.parent_quoteid IS NULL位于from flask import Flask, request, url_for app = Flask(__name__) @app.route('/') def index(): with app.test_request_context( url_for('hello'), headers=request.headers.to_list(), query_string=request.query_string ): return app.dispatch_request() @app.route('/greet') def hello(): return 'Hello, {}!'.format(request.args.get('name', 'World')) app.run() 。 HTH。

答案 1 :(得分:0)

如果您选择使父引号具有parent_quoateid = null,那么查找父引号的WHERE子句是(取决于您的特定SQL方言):

WHERE parent_quoteid = NULL

对于儿童语录是:

WHERE parent_quoteid <> NULL

如果您选择将parent_quoteid设置为父项的引用ID,那么您的where子句看起来非常相似; WHERE quoteid = parent_quoteidWHERE quoteid <> parent_quoteid

多对多关系的标准是,如果一个项目不在一个关系中,它就不应该有一行(考虑重命名&#34; quoteid&#34; to &#34; child_quoteid&#34;,并查看是否仍然有意义的行)。各种关系类型(一对一,一对多,多对多)是我所知道的数据库的唯一设计模式,更不用说规定简单的模式了。

但是,你没有问这个行是否存在。您询问parent_quoteid是否应为null。因此,让我们检查查询性能和查询的简易性。

如果这个特定的选择会影响性能或查询表有多容易,那么你想用NULL来表示父引号;查询以确定父对子与子对象时,涉及的字段和索引较少。

如果您需要使用引号表加入此表,我会指出不使用NULL作为父引号可能会导致数据库必须使用3个字段而不是2个字段为了执行加入。如果您不使用NULL,那么您可以在quoteid字段中拖动,否则只需使用parent_quoteid和您加入的表中的字段。