如何使用 SQLite 存储用户创建的列表?
How to store user-created lists with SQLite?
我正在尝试制作一个简单的应用程序,用户可以在其中制作他们想要完成的 films/books 列表。创建列表后,他们可以添加到列表,或重新排序列表中的项目。
所以目前我有一个用户 table:
CREATE TABLE User (
userid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
salt TEXT NOT NULL UNIQUE
);
和一个列表 table:
CREATE TABLE List (
listid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
listname TEXT NOT NULL,
userid INTEGER NOT NULL,
date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
date_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
FOREIGN KEY(userid) REFERENCES User(userid)
);
我现在想弄清楚的是:如何存储实际列表?列表是用户创建的,用户应该能够添加和删除它们,并根据需要重新排序列表中的项目。我还想为每个列表项存储一些元数据(例如 url 到电影的相应维基百科页面)。
起初我想,我只是将列表作为 JSON 存储在列表 table 的列中。但这在 SQL.
中似乎违反直觉
快速粗略的搜索让我找到了谈论交界处 tables 的人。我不确定我是否完全理解交界处 tables;但这是否意味着每次用户创建新列表时,我都必须为列表中的所有项目生成一个新的 table? (因此,当我在 List
table 中创建一个新行时,我还会创建一个链接到该行的新 table ListItems_ListID_Username
吗?)。
任何见解表示赞赏。如果不是很明显,我就是一个 SQL 新手。 :)
编辑:例如,如果我将每个列表项存储在 table 中,我想每个列表项看起来像这个伪模式
(orderInList INTEGER, itemname TEXT, url TEXT (nullable), listid INTEGER (foreign key to List), userid INTEGER (foreignkey to User))
您可以创建第三个 table 来存储特定用户的每个列表 owned/created 的项目,如下所示:
CREATE TABLE Users(
UserId INTEGER PK,
UserName TEXT(n)
.
.
);
CREATE TABLE Lists(
ListId INTEGER PK,
ListName TEXT(n) NOT NULL,
ListOwner INTEGER NOT NULL FK (UserId),
CreationDate DATETIME NOT NULL,
LastUpdate DATETIME NULL
);
CREATE TABLE ListItems(
Id INTEGER PK,
ListId INETGER FK,
ItemName TEXT(n),
ItemURL TEXT(n)
);
does this mean that each time a user would create a new List, I'll have to generate a new table for all of the items of the List?
没有!那是你能做的最糟糕的事情。
项目是一个实体,因此它们只有一个 table。联结 table 然后将项目链接到列表。
在你的情况下可能看起来像:
CREATE TABLE list
(listid integer
NOT NULL
AUTOINCREMENT,
userid integer
NOT NULL,
...
PRIMARY KEY (listid),
FOREIGN KEY (userid)
REFERENCES user
(userid));
CREATE TABLE item
(itemid integer
NOT NULL
AUTOINCREMENT,
...
PRIMARY KEY (itemid));
CREATE TABLE listitem
(listid integer
NOT NULL,
itemid integer
NOT NULL,
...
PRIMARY KEY (listid,
itemid),
FOREIGN KEY (listid)
REFERENCES list
(listid),
FOREIGN KEY (itemid)
REFERENCES item
(itemid));
因此,如果 ID 为 1 的用户有一个 ID 为 1 的列表,其中包含一个 ID 为 1 的项目,您就会有一条记录
.________.________._____.
| listid | userid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
'--------'--------'-----'
在list
,一条记录
.________._____.
| itemid | ... |
+--------+-----+
| 1 | ... |
'--------'-----'
在item
和一条记录
.________.________._____.
| listid | itemid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
'--------'--------'-----'
在 listitem
.
但是(!)这里要记住一件事,以及您可能不想使用该方法的原因。 ID 为 2 的用户也可以在他们的 ID 为 2 的列表中使用此项目。这看起来像:
.________.________._____.
| listid | userid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
+--------+--------+-----+
| 2 | 2 | ... |
'--------'--------'-----'
.________._____.
| itemid | ... |
+--------+-----+
| 1 | ... |
'--------'-----'
.________.________._____.
| listid | itemid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
+--------+--------+-----+
| 2 | 1 | ... |
'--------'--------'-----'
如您所见,只有一项。如果任何用户对项目进行了某些更改,则其他用户也会受到该更改的影响。现在在很多情况下,这正是人们想要的。但是在您的情况下,您可能希望某个项目对列表而言是唯一的,而不是全局的。即使 book/movie 是相同的,每个用户也可能希望有自己的记录,有自己的注释等。所以你可能不想要一个连接 table 而只是一个外键在指向列表的项目 table 中。
CREATE TABLE list
(listid integer
NOT NULL
AUTOINCREMENT,
userid integer
NOT NULL,
...
PRIMARY KEY (listid),
FOREIGN KEY (userid)
REFERENCES user
(userid));
CREATE TABLE item
(itemid integer
NOT NULL
AUTOINCREMENT,
listid integer
NOT NULL,
...
PRIMARY KEY (itemid),
FOREIGN KEY (listid)
REFERENCES list
(listid);
-- no table listitem
现在一个项目只属于一个列表,对该项目所做的任何更改只会影响该列表中的一个项目。
当然你也可以让项目全球唯一但用户不能改变。为了让用户有机会在他们的列表中拥有他们自己的项目数据,您可以在可以存储此信息的 listitem
中添加列。
我正在尝试制作一个简单的应用程序,用户可以在其中制作他们想要完成的 films/books 列表。创建列表后,他们可以添加到列表,或重新排序列表中的项目。
所以目前我有一个用户 table:
CREATE TABLE User (
userid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
salt TEXT NOT NULL UNIQUE
);
和一个列表 table:
CREATE TABLE List (
listid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
listname TEXT NOT NULL,
userid INTEGER NOT NULL,
date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
date_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
FOREIGN KEY(userid) REFERENCES User(userid)
);
我现在想弄清楚的是:如何存储实际列表?列表是用户创建的,用户应该能够添加和删除它们,并根据需要重新排序列表中的项目。我还想为每个列表项存储一些元数据(例如 url 到电影的相应维基百科页面)。
起初我想,我只是将列表作为 JSON 存储在列表 table 的列中。但这在 SQL.
中似乎违反直觉快速粗略的搜索让我找到了谈论交界处 tables 的人。我不确定我是否完全理解交界处 tables;但这是否意味着每次用户创建新列表时,我都必须为列表中的所有项目生成一个新的 table? (因此,当我在 List
table 中创建一个新行时,我还会创建一个链接到该行的新 table ListItems_ListID_Username
吗?)。
任何见解表示赞赏。如果不是很明显,我就是一个 SQL 新手。 :)
编辑:例如,如果我将每个列表项存储在 table 中,我想每个列表项看起来像这个伪模式
(orderInList INTEGER, itemname TEXT, url TEXT (nullable), listid INTEGER (foreign key to List), userid INTEGER (foreignkey to User))
您可以创建第三个 table 来存储特定用户的每个列表 owned/created 的项目,如下所示:
CREATE TABLE Users(
UserId INTEGER PK,
UserName TEXT(n)
.
.
);
CREATE TABLE Lists(
ListId INTEGER PK,
ListName TEXT(n) NOT NULL,
ListOwner INTEGER NOT NULL FK (UserId),
CreationDate DATETIME NOT NULL,
LastUpdate DATETIME NULL
);
CREATE TABLE ListItems(
Id INTEGER PK,
ListId INETGER FK,
ItemName TEXT(n),
ItemURL TEXT(n)
);
does this mean that each time a user would create a new List, I'll have to generate a new table for all of the items of the List?
没有!那是你能做的最糟糕的事情。
项目是一个实体,因此它们只有一个 table。联结 table 然后将项目链接到列表。
在你的情况下可能看起来像:
CREATE TABLE list
(listid integer
NOT NULL
AUTOINCREMENT,
userid integer
NOT NULL,
...
PRIMARY KEY (listid),
FOREIGN KEY (userid)
REFERENCES user
(userid));
CREATE TABLE item
(itemid integer
NOT NULL
AUTOINCREMENT,
...
PRIMARY KEY (itemid));
CREATE TABLE listitem
(listid integer
NOT NULL,
itemid integer
NOT NULL,
...
PRIMARY KEY (listid,
itemid),
FOREIGN KEY (listid)
REFERENCES list
(listid),
FOREIGN KEY (itemid)
REFERENCES item
(itemid));
因此,如果 ID 为 1 的用户有一个 ID 为 1 的列表,其中包含一个 ID 为 1 的项目,您就会有一条记录
.________.________._____.
| listid | userid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
'--------'--------'-----'
在list
,一条记录
.________._____.
| itemid | ... |
+--------+-----+
| 1 | ... |
'--------'-----'
在item
和一条记录
.________.________._____.
| listid | itemid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
'--------'--------'-----'
在 listitem
.
但是(!)这里要记住一件事,以及您可能不想使用该方法的原因。 ID 为 2 的用户也可以在他们的 ID 为 2 的列表中使用此项目。这看起来像:
.________.________._____.
| listid | userid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
+--------+--------+-----+
| 2 | 2 | ... |
'--------'--------'-----'
.________._____.
| itemid | ... |
+--------+-----+
| 1 | ... |
'--------'-----'
.________.________._____.
| listid | itemid | ... |
+--------+--------+-----+
| 1 | 1 | ... |
+--------+--------+-----+
| 2 | 1 | ... |
'--------'--------'-----'
如您所见,只有一项。如果任何用户对项目进行了某些更改,则其他用户也会受到该更改的影响。现在在很多情况下,这正是人们想要的。但是在您的情况下,您可能希望某个项目对列表而言是唯一的,而不是全局的。即使 book/movie 是相同的,每个用户也可能希望有自己的记录,有自己的注释等。所以你可能不想要一个连接 table 而只是一个外键在指向列表的项目 table 中。
CREATE TABLE list
(listid integer
NOT NULL
AUTOINCREMENT,
userid integer
NOT NULL,
...
PRIMARY KEY (listid),
FOREIGN KEY (userid)
REFERENCES user
(userid));
CREATE TABLE item
(itemid integer
NOT NULL
AUTOINCREMENT,
listid integer
NOT NULL,
...
PRIMARY KEY (itemid),
FOREIGN KEY (listid)
REFERENCES list
(listid);
-- no table listitem
现在一个项目只属于一个列表,对该项目所做的任何更改只会影响该列表中的一个项目。
当然你也可以让项目全球唯一但用户不能改变。为了让用户有机会在他们的列表中拥有他们自己的项目数据,您可以在可以存储此信息的 listitem
中添加列。