SQL Zero to One或Boolean

时间:2011-11-17 06:52:48

标签: sql database database-design

我目前正在将一大堆用户数据从CSV电子表格迁移到SQL数据库,设计架构和所有爵士乐。

此时,Users表如下所示:

CREATE TABLE Users
(
    id      INTEGER NOT NULL AUTO_INCREMENT,

    name        VARCHAR(48) NOT NULL,
    alias       VARCHAR(24) NOT NULL UNIQUE,
    email       VARCHAR(128) NOT NULL,

    date_of_birth   DATE,
    location    VARCHAR(24) NOT NULL,

    date_joined DATE,

    ...

    PRIMARY KEY (id)
);

我们(该集团)希望尽快为某些活动和报道测试电子邮件订阅服务;这将通过查看数据库中订阅的人来管理。

我最初的想法只是向Users表添加一个布尔值,表示它们是否已订阅,但是编辑这样的架构似乎是一种不好的做法。

我的第二个想法是:

CREATE TABLE Subscribers
(
    uid     INTEGER NOT NULL,
    PRIMARY KEY (uid)
    FOREIGN KEY (uid) REFERENCES Users(id)
);

这两种方法的优点是什么?考虑到测试可能是实验性的,哪种情况最适合我的情况。

4 个答案:

答案 0 :(得分:3)

哪种行动方案适合,主要取决于预期的用例。如果您只能订阅一个时事通讯,那么布尔标志版本应该是首选,因为找到具有

的订阅者要快得多
select * from User where subscribed = 1 

与使用可能很大的Subscribers表进行连接。但是,如果您可以订阅多个简报,这意味着每个简报会在您的用户表格中添加一列(例如subscribedToProductAnnouncementssubscribedToHolidayNewsletter等)。如果你有很多用户(数百万),如果你遇到性能问题可能仍然是一个选项,但除非你真的得到使用Subscribers表的性能问题,否则你会更好,因为你可以添加更多的新闻简报必须一直更改数据库架构。这将要求您使用一个字段扩展Subscribers表:

CREATE TABLE Subscribers
(
    id      LONG PRIMARY KEY AUTO_INCREMENT,
    newsletterId INTEGER NOT NULL  -- the ID of the newsletter that the user is subscribed to
    uid     INTEGER NOT NULL,
    FOREIGN KEY (uid) REFERENCES Users(uid)
);

我也会在LONG idSubscribers中找到INTEGER,因为订阅可能会来来去去,最终可能达到Subscriptions的20亿限制。并且可能将该表重命名为{{1}}也是一个好主意,因为它实际上包含订阅而不是订阅者。

答案 1 :(得分:1)

Subscribers表方法的优点包括:

  • 它是一个更高 - 实际上,最高 - 正常的形式,是6NF;
  • 它更便携,例如并非所有SQL产品都具有布尔类型;

this article by Joe Celko还有其他原因。

发布的Subscribers表有一些缺陷。 uid列应具有唯一约束。自动增量列是多余的。外键应该具有引用操作ON DELETE CASCADE(并且ON UPDATE CASCADE可能在将来证明是有用的。)

答案 2 :(得分:0)

你最好使用布尔...你的第二个想法,如果用户想要取消订阅,你必须从数据库中删除它们这是一个非常糟糕的主意

那就是布尔值可以更好地确定该用户是否允许您向他们发送电子邮件

答案 3 :(得分:-1)

(旁注:用户没有uid列。)

订阅者不需要代理键。它只能有一列,它是Users(id)上的主键和外键。