建立表之间的关系

时间:2018-01-13 21:29:44

标签: mysql

我需要一个可搜索的数据库,其中包含消息,我可以附加标签,以及查看它们是否已被使用,何时何地。

例如,我收到以下消息"嗨!我住在斯德哥尔摩,正在寻找一个勤杂工。我在你的个人资料中看到你拥有一个工具箱,因为我自己不拥有任何工具,除了螺丝刀,我希望雇用你是最好的,因为你可以自带工具!请尽快与我联系!"

对于这条消息,我想附上标签"斯德哥尔摩,杂工,工具箱,螺丝刀和工具"。

在搜索数据库时,我希望能够找到包含标签的所有消息" Stockholm"和"工具箱"。

如果我决定使用上面的这条消息,并使用它,我希望能够设置它使用2018-02-11 11.52使用名称" John Doe"在网站" findahandyman.site"。

现在,这都是虚构的,我将使用完全不同的消息与其他标签,地方等。但情景是真实的。但是,我不知道最好的方法是做什么。

我这样想:

  tbl-tags
 ----------
|id  | tag |
 ----------

  tbl-messages
 --------------
| id | message |
 --------------

          tbl-used
 -------------------------
| id | date | name | site |
 -------------------------

然后构建一个视图,我可以在其中搜索消息,使用标签#1#2#3等进行注册。

我在想什么?如果我是,我怎么能将它们全部联系起来以及如何构建视图。如果我不是,我该怎么想?而且,如何将它们全部联系起来并根据你的建议构建视图?

2 个答案:

答案 0 :(得分:1)

在我看来,你需要这样做:

1。)像这样制作父表

create table tbl_tags
(
   tagName VARCHAR(50) NOT NULL,
   dateAdded datetime NULL,
   primary key(tagName) 
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;

使用tbl_message创建id表作为主键(tagName在这里是主要的,因为这样标记名称不会重复),如下所示:

create table tbl_messages
(
   message_ID INT(11) NOT NULL AUTO_INCREMENT,
   message text NOT NULL,
   dateAdded NULL,
   primary key(message_ID) 
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;

对于tbl_used我会使它成为一个包含三列的映射表。一列是message_ID(表tbl_messages中的外键),另一列是date and time,我还要在此添加id作为主要内容如果多个用户同时尝试使用相同的消息,请避免收到错误。

create table tbl_used
(
   used_ID INT(11) NOT NULL AUTO_INCREMENT,
   message_ID INT(11) NOT NULL,
   timeOfUse dateTime NOT NULL,
   PRIMARY KEY (`used_ID`),
   FOREIGN KEY (`message_ID`) REFERENCES `tbl_messages` (`message_ID`) ON UPDATE CASCADE
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;

2。)创建另一个映射表,将messagestags表相互关联:

create table tbl_messages_x_tbl_tags
(
    message_ID INT(11) NOT NULL,
    tagName VARCHAR(50) NOT NULL,
    PRIMARY KEY (`message_ID`, `tagName`),
    FOREIGN KEY (`message_ID`) REFERENCES `tbl_messages` (`message_ID`) ON UPDATE CASCADE,
    FOREIGN KEY (`tagName`) REFERENCES `tbl_tags` (`tagName`) ON UPDATE CASCADE
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;

您会注意到,您将无法使用任意内容填充映射表中的外键列。您只能从各自的父表中插入有效值。这意味着您的映射表数据是一致的。

要填写表格,首先需要填写 parent tables tbl_messagestbl_tags),然后您可以填充 {{ 1}} mapping tablestbl_messages_x_tbl_tags)。

在插入新邮件时,您只需检查新标记并将新标记插入表tbl_used(如果它们尚未存在)。然后将消息添加到tbl_tags并使用tbl_messages行填充映射表tbl_messages_x_tbl_tags

之后,在每次使用消息时,您只需写入数据库:

(message_ID, tagName)

答案 1 :(得分:-2)

  tbl-tags
 ----------
|id  | tag |
 ----------

tbl-message-tags
 ----------------------
| id | tag_id | msg_id |
 ----------------------

tbl-messages
 --------------
| id | message |
 --------------

          tbl-used
 -------------------------
| id | date | name | site |
 -------------------------

创建表格(如果需要,可以添加约束):

create table tbl_tags(id mediumint not null auto_increment, tag varchar(255) not null, primary key(id));
create table tbl_messages(id mediumint not null auto_increment, message text not null, primary key(id));
create table tmt(tag_id mediumint not null, msg_id mediumint not null, primary key(tag_id, msg_id));

插入一些测试数据:

insert into tbl_tags(tag) values ('tag0'), ('tag1');
insert into tbl_messages(message) values ('msg1'), ('msg2'), ('msg3'), ('msg4'), ('msg5');
insert into tbl_message_tags(tag_id, msg_id) values (1, 1), (0, 1), (1, 2), (0, 3);

在此之后,您可以进行如下查询:

select tag from tbl_tags join (select tag_id from tbl_messages join tbl_message_tags on id = msg_id where msg_id = 1) as t on id = t.tag_id;

结果将是:

 ----------
| id | tag |
|----|-----|
| 1  | tag0|
|----|-----|
| 2  | tag1|
 ---- -----

此外,您需要将消息标识符字段添加到tbl-used以获取消息,并与每行链接。

另一种变体(不是优选的):

只有当您想在许多消息中使用类似标签时才需要tbl-tags(在收到消息后,您可以对案例进行规范化,将其拆分并仅将新标签附加到tbl-tags),但如果您不需要这种类型的优化,您可以在消息表中使用“数组字段”(即,在mysql中,您可以以类似的方式执行此操作:How can I simulate an array variable in MySQL?)。