如何使用 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 中添加列。