关于在不同表中引用为外键的主键上创建的索引(SQLite3)

时间:2014-06-08 00:07:21

标签: database database-design sqlite indexing foreign-keys

我的数据库设计方案如下:人们访问相互联网并提出匹配的匹配制作者。例如,人A访问匹配器X,人B访问匹配器Y,其中A不等于B并且对X,Y没有约束,即它们可以相同或不同。

create table matchmaker ( id TEXT primary key, address TEXT );

create table people ( id TEXT primary key, name TEXT, gender TEXT, matchmaker_id TEXT,
    foreign key(matchmaker_id) references matchmaker(id));

create table married_couples ( id1 TEXT, id2 TEXT,
    foreign key (id1) references people(id), 
    foreign key (id2) reference people(id));

然后,为了更快地访问数据库:

create index matchmaker_index on matchmaker(id);
create index people_index on people(id);

我的问题是基于以下查询,与他们配对的人生成红娘对的元组。

select a.id, b.id, e.id1, e.id2
from matchmaker as a, matchmaker as b, 
people as c, people as d, 
married_couples as e
where e.id1 = c.id and c.id = a.id and 
e.id2 = d.id and d.id = b.id;

对于上面的查询,两个matchmaker_index和people_index是否足够,或者 是否需要两个(其他)索引如下?

create index matchmaker_people_index on people(id, matchmaker_id);
create index married_couples_index on married_couples(id1, id2);

其他信息:

1)matchmaker有20074个唯一条目;

2)人们有20494819个独特的条目;

3)married_couples ?? (我还没有获得这些信息,但它会变得很大)

此外,married_couples可能会有重复的条目。所以, 创建相关索引后,将运行查询以删除重复项,如下所示:

delete from married_couples 
where rowid not in ( select min(rowid)
    from married_couples
    group by id1, id2);

1 个答案:

答案 0 :(得分:0)

SQLite会自动为声明为primary keyunique的列生成索引。 FAQ, see question 7。所以这两个指标

create index matchmaker_index on matchmaker(id);
create index people_index on people(id);

是重复的。放下它们。

此索引

create index matchmaker_people_index on people(id, matchmaker_id);

可能有帮助。

  

此外,married_couples可能会有重复的条目。

消除这种可能性。添加主键 CHECK约束。

create table married_couples ( 
  id1 TEXT, id2 TEXT,
    foreign key (id1) references people(id), 
    foreign key (id2) references people(id),
    primary key (id1, id2),
    check (id1 < id2)
);

主键也提供索引。

当你谈到婚姻时,Mike和Mindy之间的婚姻是Mindy和Mike之间婚姻的重复。 CHECK约束可以防止这种微妙的重复。它还可以防止人们嫁给自己。

我不确定你和艾菲尔铁塔结婚的女人可能会怎么做。

您可以非常简化原始查询。学习ANSI连接是一个好主意。

select id1, id2, c.matchmaker_id m_id1, d.matchmaker_id m_id2
from married_couples a
inner join people c
  on c.id = a.id1
inner join people d
  on d.id = a.id1;