2016-05-27 47 views
2

我是新的数据库,我打算与你分享2数据库表设计在这里,我只想知道哪一个是最好的设计,为什么?这是最好的数据库设计为mysql

第一个我创建了一个用户表,主题表和user_subject表。

在用户表中我保存用户信息,并在主题我保存主题。 IN user_subject中我保存了用户ID和主题ID。

CREATE TABLE IF NOT EXISTS `subjects` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `users` 
-- 

CREATE TABLE IF NOT EXISTS `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `user_subjects` 
-- 

CREATE TABLE IF NOT EXISTS `user_subjects` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) NOT NULL, 
    `subject_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

2一个>

CREATE TABLE IF NOT EXISTS `subjects` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 



CREATE TABLE IF NOT EXISTS `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `subject_name` varchar(2000) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

我保存的用户,它的在user表科目昏迷(,),鲱鱼,而不是创建另一个表保存用户和主题标识。

我的第二个问题是最好的,因为我们不需要在第三个表中保存数据。请告诉我哪一个是最好的和持久的未来。

+4

第一个好得多。将数据保存为逗号分隔值,限制了使用索引进行查询的能力。 **顺便说一句**你不需要在第三张桌子上有“ID”。只需用'(用户,主题)'创建一个复合键' –

+0

@JuanCarlosOropeza是正确的。第一个好多了。 – Harman

回答

2

第一个版本好多了,好多了。这里有一些你不想使用逗号分隔的字符串的原因:

  • SQL没有特别好的字符串函数 - 基本的,但没有更多。
  • 当您将值存储在分隔字符串中时,数据库无法验证数据。使用单独的表格可以使用外键约束。
  • 逗号分隔列上的查询无法使用标准索引(尽管可能使用全文索引)。
  • 使用逗号分隔的字符串,数据库无法验证主题是否唯一。

第一种方法使用联结表,它是在关系数据库中实现此逻辑的更好方法。

0

这是确定使用第二种方式IF:

1)主题只有一个的重要性(名称)

2)值唯一标识对象的值(即没有二级学科具有相同的名称),或者不需要区分同名的两个主题

一般而言,第一种方式更好,因为如果您突然决定为主题赋予新的值(例如年龄),则不必重做您的整个桌子结构。

0

无论如何,第二个解决方案并不是很好,因为您不能使用连接或索引。

哪个解决方案最好,取决于用户和主题之间的关系类型。 如果每个主题只属于一个用户,并且每个用户可以有任意数量的主题,这意味着您有一对多的关系,但应该将user_id添加到表主题。

如果任何主题可以属于多个用户,并且每个用户可以有多个主题,则应该使用第一个解决方案和第三个映射表(这将是多对多关系)。

在这两种情况下,你可以表达使用一个简单的SQL很容易且干净以下查询联接:

  • 该科目属于给定用户
  • 哪些用户拥有含有一定的表达的名称科目
  • 这是给定主题的用户(是第二种情况下的用户)