如何将多个选项存储在一个表中?

我想devise一个结果计算的应用程序。

首先,我需要知道如何将logging存储在MySQL数据库中,以便学生可以拥有许多课程,例如,学生A可以有6个主题,而学生B可以有12个主题。

在这种情况下,我需要知道我怎么可能devise一个数据库结构,它允许一个字段以一个数组的forms存储尽可能多的主题。

任何build议或更好的方式来处理这将高度赞赏。

请仔细阅读数据标准化 , 一般索引概念和外键约束,以保持数据的清晰性和参照完整性。 这会让你走。

在数据中存储数据看起来很自然,但对于数据库引擎来说,大多数情况下性能没有索引使用。 而且,你会发现在第二天,获取和维护你的数据将是一场噩梦。

下面的内容应该能帮助你在鼓捣时取得好的开始。 也join 。

create table student ( studentId int auto_increment primary key, fullName varchar(100) not null -- etc ); create table dept ( deptId int auto_increment primary key, deptName varchar(100) not null -- Economics -- etc ); create table course ( courseId int auto_increment primary key, deptId int not null, courseName varchar(100) not null, -- etc CONSTRAINT fk_crs_dept FOREIGN KEY (deptId) REFERENCES dept(deptId) ); create table SCJunction ( -- Student/Course Junction table (aka Student is taking the course) -- also holds the attendance and grade id int auto_increment primary key, studentId int not null, courseId int not null, term int not null, -- term (I am using 100 in below examples for this term) attendance int not null, -- whatever you want, 100=always there, 0=he must have been partying, grade int not null, -- just an idea -- See (Note Composite Index) at bottom concerning next two lines. unique key(studentId,courseId,term), -- no duplicates allowed for the combo (note student can re-take it next term) key (courseId,studentId), CONSTRAINT fk_sc_student FOREIGN KEY (studentId) REFERENCES student(studentId), CONSTRAINT fk_sc_courses FOREIGN KEY (courseId) REFERENCES course(courseId) ); 

创buildtesting数据

 insert student(fullName) values ('Henry Carthage'),('Kim Billings'),('Shy Guy'); -- id's 1,2,3 insert student(fullName) values ('Shy Guy'); insert dept(deptName) values ('History'),('Math'),('English'); -- id's 1,2,3 insert course(deptId,courseName) values (1,'Early Roman Empire'),(1,'Italian Nation States'); -- id's 1 and 2 (History dept) insert course(deptId,courseName) values (2,'Calculus 1'),(2,'Linear Algebra A'); -- id's 3 and 4 (Math dept) insert course(deptId,courseName) values (3,'World of Chaucer'); -- id 5 (English dept) -- show why FK constraints are important based on data at the moment insert course(deptId,courseName) values (66,'Fly Fishing 101'); -- will generate error 1452. That dept 66 does not exist -- That error is a good error to have. Better than faulty data -- Have Kim (studentId=2) enrolled in a few courses insert SCJunction(studentId,courseId,term,attendance,grade) values (2,1,100,-1,-1); -- Early Roman Empire, term 100 (made up), unknown attendance/grade insert SCJunction(studentId,courseId,term,attendance,grade) values (2,4,100,-1,-1); -- Linear Algebra A insert SCJunction(studentId,courseId,term,attendance,grade) values (2,5,100,-1,-1); -- World of Chaucer -- Have Shy Guy (studentId=3) enrolled in one course only. He is shy insert SCJunction(studentId,courseId,term,attendance,grade) values (3,5,100,-1,-1); -- Early Roman Empire, term 100 (made up), unknow attendance/grade -- note if you run that line again, the Error 1062 Duplicate entry happens. Can't take same course more than once per term 

一些简单的问题。

什么课程在哪个部门?

显示所有,使用表别名(缩写),使打字less,可读性(有时)更好

 select c.courseId,c.courseName,d.deptId,d.deptName from course c join dept d on c.deptId=d.deptId order by d.deptName,c.courseName -- note the order +----------+-----------------------+--------+----------+ | courseId | courseName | deptId | deptName | +----------+-----------------------+--------+----------+ | 5 | World of Chaucer | 3 | English | | 1 | Early Roman Empire | 1 | History | | 2 | Italian Nation States | 1 | History | | 3 | Calculus 1 | 2 | Math | | 4 | Linear Algebra A | 2 | Math | +----------+-----------------------+--------+----------+ 

这个学期谁正在参加乔course课程?

(知道courseId = 5)

下面的好处来自于我们在SCJunction中的一个综合指数。 组合是多于一列的索引。

 select s.StudentId,s.FullName from SCJunction j join student s on j.studentId=s.studentId where j.courseId=5 and j.term=100 +-----------+--------------+ | StudentId | FullName | +-----------+--------------+ | 2 | Kim Billings | | 3 | Shy Guy | +-----------+--------------+ 

金·比林斯是否参加了这个词?

 select s.StudentId,s.FullName,c.courseId,c.courseName from SCJunction j join student s on j.studentId=s.studentId join course c on j.courseId=c.courseId where s.studentId=2 and j.term=100 order by c.courseId DESC -- descending, just for the fun of it +-----------+--------------+----------+--------------------+ | StudentId | FullName | courseId | courseName | +-----------+--------------+----------+--------------------+ | 2 | Kim Billings | 5 | World of Chaucer | | 2 | Kim Billings | 4 | Linear Algebra A | | 2 | Kim Billings | 1 | Early Roman Empire | +-----------+--------------+----------+--------------------+ 

金不知所措,所以放下math课

 delete from SCJunction where studentId=2 and courseId=4 and term=100 

运行上面的select陈述金正在采取:

 +-----------+--------------+----------+--------------------+ | StudentId | FullName | courseId | courseName | +-----------+--------------+----------+--------------------+ | 2 | Kim Billings | 5 | World of Chaucer | | 2 | Kim Billings | 1 | Early Roman Empire | +-----------+--------------+----------+--------------------+ 

啊,更容易的术语。 爸爸不会高兴的。

注意诸如SCJunction.term之类的东西。 关于这件事可以写得很多,我现在大部分都会跳过它,除了说它也应该放在某个地方。 你可能希望你的术语看起来更像SPRING2015,而不是一个整数。

至于id的去。 这是我会这样做的方式。 这是个人喜好。 这将需要知道id#的,查找他们。 其他人可以select一门课程,如HIST101而不是17门课。这些课程的可读性非常高(但是在索引中很慢(几乎没有)),所以对你最好。

注综合指数

综合索引(INDEX是指KEY,反之亦然)是一个结合了多列的快速数据检索。 在SCJunction表中为这两个组合翻转订单,以便根据数据后面的查询范围,数据库引擎可以根据要去的最后一列select最快的检索使用哪个索引。

至于唯一的关键字#1,它旁边的注释强调没有重复(即垃圾数据)是不言自明的。 例如,学生1课程1学期1不能在该表中存在两次。

要理解的关键概念是索引中列名left-mostsorting的概念。

对于仅限studentId查询,则使用studentId列出studentId的键( left-most )。 在仅限courseId查询中,使用最左侧courseId的密钥。 在studentId和courseId之后的查询中,数据库引擎可以决定使用哪个组合键。

当我说“追究”时,我是指在on clausewhere clause条件。

如果没有这两个组合键(其中第一列和第二列被翻转),那么在查询列中不是left-most索引的查询中,您将不会受益于密钥使用情况,并且数据缓慢扫描回来。

那么,这两个指标就结合了以下两个概念

  • 基于最左边或两者的快速数据检索(studentId和courseId列)
  • 根据studentId,courseId和期限值强制执行该表中数据的非重复

外卖

重要的是,连接表可以快速检索索引,并且数据与逗号分隔的数据(数组心态)的理智pipe理挤在一个列中,以及使用这种构造的所有困难。

为了完整起见,不是一般推荐的解决scheme:

MySQL提供了JSON数据types ,它允许以JSON格式存储和检索对象和数组。

这样,您可以将整个对象和数组存储到一个字段中,因为数组看起来像:

  ['subject_1', 'subject_2', 'subject_3'] 

特别是初学者不知道这一点,他们又用逗号分隔的string实现或使用依赖于语言的序列化/反序列化方法重新发明轮子。

至lessJSON是非常常用的,并且很容易被parsing为数据交换格式。

在MySQL字段中使用存储数组和对象的有效用例,例如用于速度优化,或者当您仍然想要保存在数据库中的未知或dynamic属性时。

然而,作为一个经验法则,如果您依赖于将对象和数组存储到MySQL中,那么您的数据库devise很可能被破坏。