Sql 推特的简化版本。了解数据库中表之间的多对多关系
我正在阅读的是一种存储推特、用户、喜好等信息的关系数据库。描述并绘制了数据库方案 作为一名Android开发人员,我使用SQLite编写了我的示例。以下是我编写代码的方式:Sql 推特的简化版本。了解数据库中表之间的多对多关系,sql,database-design,Sql,Database Design,我正在阅读的是一种存储推特、用户、喜好等信息的关系数据库。描述并绘制了数据库方案 作为一名Android开发人员,我使用SQLite编写了我的示例。以下是我编写代码的方式: create table users (_id integer primary key, username text unique, first_name text, last_name text); create table tweets (_id integer primary key, content text, cr
create table users (_id integer primary key, username text unique, first_name text, last_name text);
create table tweets (_id integer primary key, content text, created_at integer, user_id integer, foreign key(user_id) references users(_id));
create table connections (_id integer primary key, follower_id integer, followee_id integer, created_at integer, foreign key(follower_id) references users(_id), foreign key (followee_id) references users(_id));
create table favorites (_id integer primary key, user_id integer, tweet_id integer, foreign key (user_id) references users(_id), foreign key (tweet_id) references tweets(_id));
现在让我们插入一些数据
用户:
insert into users values (1, 'user1', 'Lorem', 'Ipsum');
insert into users values (2, 'user2', 'Dolor', 'Sit');
insert into users values (3, 'user3', 'Foo', 'Bar');
insert into users values (4, 'user4', 'Qwerty', 'Trewq');
一些推文:
insert into tweets values(10, '1 Tweet from user1', 1100, 1);
insert into tweets values(11, '2 Tweet from user1', 1101, 1);
insert into tweets values(12, '3 Tweet from user1', 1102, 1);
insert into tweets values(13, '4 Tweet from user1', 1103, 1);
insert into tweets values(14, '1 Tweet from user2', 1103, 2);
insert into tweets values(15, '2 Tweet from user2', 1103, 2);
insert into tweets values(16, '1 Tweet from user3', 1103, 3);
insert into tweets values(17, '2 Tweet from user3', 1103, 3);
insert into tweets values(18, '1 Tweet from user4', 1107, 4);
收藏夹(与喜欢的内容相同):
关于数据库方案有一个问题:
你认为你能支持我们的数据库设计能力吗
为给定用户显示页面,其中包含他们最近发布的
至少喜欢一次
是的,这就是为什么查询:
sqlite> select favorites._id, tweets._id as tweet_row_id, tweets.content from favorites join tweets on tweets.user_id=1 and tweets._id = favorites.tweet_id order by tweets._id desc limit 1;
_id tweet_row_id content
---------- ------------ ------------------
2 13 4 Tweet from user1
说明:
左侧的数据集是表收藏夹。正确的数据集是表tweets。我加入这两个数据集。然后,tweets.user_id=1和tweets.\u id=favorites.tweet_id
作为布尔表达式为结果数据集的每一行求值。如果结果为true,则包含该行<代码>按推文排序。_iddesc用于获取最新推文(推文越大。_id越新)<代码>限制用于限制行数。如果用户多年来一直在使用我们类似Twitter的应用程序,我们将显示最新的10或20条推文
我的问题。
notnull
、unique
和其他列约束1:n
和n:m
我假设你的最后一句话就是你的实际问题:
为什么我们这里需要多对多?在我的方案中,我只使用一对多
用户tweets的关系是1:n
在对象中思考
- 用户(id、名称等)
- 推特(id、作者(用户上的FK)、日期时间、内容等)
- 比如(id、userid、tweetid、datetime等)
1:n
-关系,推特与此映射之间存在1:n
-关系。这两个
1:n
-关系一起构成m:n
-关系。
现在每个tweet都可以被很多用户喜欢,每个用户也可以喜欢很多tweet,但是一个用户不应该(可能)两次喜欢同一条tweet(唯一键,甚至两列PK?)。您可能会引入检查约束,以确保喜欢的用户和作者的用户ID不相同(不喜欢您自己的tweet)
作为旁注:
我的数据库方案有什么问题吗
您不应该在不命名约束的情况下创建约束
CREATE TABLE Dummy
(
ID INT IDENTITY CONSTRAINT PK_Dummy PRIMARY KEY
,UserID INT NOT NULL CONSTRAINT FK_Dummy_UserID FOREIGN KEY REFERENCES User(id)
,...
)
如果这个数据库曾经安装在不同的系统上,它们将得到不同的(随机)名称,未来的升级脚本将使您陷入最深的痛苦
更新:侧注示例
在你的评论中,你会问,最后一句话是关于什么的。。。试试这个
CREATE DATABASE testDB;
GO
USE testDB;
GO
CREATE TABLE testTbl1(ID INT IDENTITY PRIMARY KEY,SomeValue INT UNIQUE);
CREATE TABLE testTbl2(ID INT IDENTITY PRIMARY KEY,FKtoTbl1 INT NOT NULL FOREIGN KEY REFERENCES testTbl1(ID));
GO
CREATE TABLE testTbl3(ID INT IDENTITY CONSTRAINT PK_3 PRIMARY KEY,SomeValue INT CONSTRAINT UQ_3_SomeValue UNIQUE);
CREATE TABLE testTbl4(ID INT IDENTITY CONSTRAINT PK_4 PRIMARY KEY,FKtoTbl3 INT NOT NULL CONSTRAINT FK_4_FKtoTbl3 FOREIGN KEY REFERENCES testTbl3(ID));
GO
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS;
GO
USE master;
GO
DROP DATABASE testDB;
GO
在结果中的列上,如下所示:
CONSTRAINT_NAME
------------------------------
PK__testTbl1__3214EC27ABEA2C0C
UQ__testTbl1__0E5C381C04C8AF66
PK__testTbl2__3214EC272784631C
FK__testTbl2__FKtoTb__1367E606
PK_3
UQ_3_SomeValue
PK_4
FK_4_FKtoTbl3
如果此脚本运行两次,则给定的名称将保持为您定义的名称。其他名称将获得一个随机名称,如PK_uuutesttbl1_uuu3214ec27abea2c0c
。现在想象一下,您需要为几个已安装的系统创建一个升级脚本,其中必须删除或修改一个约束。如果你不知道它的名字,你会怎么做?如果这个数据库安装在不同的系统上,它们会变得不同(随机)名字和未来的升级脚本会让你感到最痛苦…
我不理解这部分这两个1:n关系一起构成了m:n关系
我不确定我是否理解这部分。当一个作者写很多书,而同一本书可以由几个作者写时,两个实体(由表表示)之间存在多对多关系:作者和书。但是,对于我的例子,哪些实体有多对多的关系?@ MakSimdMiRiEV来建模A<代码> M:N -关系,中间需要一个表。在您的示例中,这是带有FK to Author和FK to Book的AuthorBook
。简单案例1 book 1 autor是一行。1 autor many books是每本书的一行,所有的书都有相同的autor,many autor 1 book与以前一样,但反之亦然,m:n是两者的混合体……我说的“我的例子”是指来自question@MaksimDmitriev没那么复杂:-)。。。一个表tweet,一个表用户。一个用户可以发布多条推文,每条推文只有一位作者。这与1:n
有关。现在很多用户可以喜欢很多推文。这里您需要一个映射表,可以在其中看到多个组合。询问哪些用户喜欢某条推文?或者询问特定用户喜欢哪些推文?这需要m:n
-关系。。。
CONSTRAINT_NAME
------------------------------
PK__testTbl1__3214EC27ABEA2C0C
UQ__testTbl1__0E5C381C04C8AF66
PK__testTbl2__3214EC272784631C
FK__testTbl2__FKtoTb__1367E606
PK_3
UQ_3_SomeValue
PK_4
FK_4_FKtoTbl3