数据库表设计困境,很多复选框?

时间:2011-11-29 22:09:46

标签: php mysql html database-design cakephp

我想先说谢谢你们,你们对我都很好。

我会直接回答这个问题。

拥有超过400列的表是不是很糟糕?

我的网页表单主要包含需要复选框答案的问题。 如果不是更多,复选框的总数最多可以运行400个。

我实际上对其中一个表单进行了建模,并将每个复选框放在一列中(花了我几个小时的时间)。 由于我不熟悉数据库设计,我觉得这不是正确的方法。

所以我读到某些人使用序列化函数,将一组复选框作为文本存储在列中。

我只是想知道这是存储这些复选框的最佳方式。

哦,还有一些信息我将使用cakephp orm和这些表。

提前再次感谢。

我的数据库看起来像这样

表:患者,表:admitForm,表:SomeOtherFOrm

每个表格表都有一个PatientId

如上所述,我首先尝试为每个表单创建一个表,然后将每个复选框放在一列中。这让我永远这样做。

所以我读了一些每个问题的序列化复选框是个好主意

所以即时提问将是一个很好的方法。

4 个答案:

答案 0 :(得分:2)

对于有多个选项的问题,只需添加另一个表格。

没有人问你的问题是你是否需要进行数据挖掘或将这些复选框问题的答案放入查询中的where子句中。如果您不需要对这些答案中包含的数据外观进行任何查询,那么您只需将它们序列化为几个字段即可。你甚至可以将它们打包成数字。 (如果你打包数据,所有追随你的人都会恨你)

这是我对架构的想法。

The Database Schema Pictorial

答案 1 :(得分:1)

我想我会把它分成3个表。一个表代表任何实体正在回答问题。第二个表格包含问题本身。最后,每当第一个表中的实体选中该问题的复选框时,将使用第一个表的主键和第二个表中的问题的id填充第三个联结表。

答案 2 :(得分:1)

通常400列意味着您的数据可以更好地规范化并分成多个表。但是,根据用例,400列可能实际上是合适的。可能适合的一个示例是,如果您在每个查询中都需要这些字段,并且需要使用这些列过滤记录(即:在WHERE子句中使用它们)......在这种情况下,SQL JOIN可能会更昂贵而不是人口稀少的“宽”桌子。

如果您永远不需要使用SQL根据这些“复选框”过滤掉记录(我猜它们是/不是boolean / tinyint类型值),那么序列化是一种有效的方法。如果我需要在查询表时大多数时候使用复选框值,我会选择这条路线,但不需要在WHERE子句中使用它们。

如果您不需要这些复选框值,或者只需要一小部分复选框值,那么对于您的表的大多数请求,您可能应该将表分成多个表。一种方法是使用一个包含复选框值(id,record_id,checkbox_name,checkbox_value)的表,其中record_id是主表记录的id。这意味着您的主要记录与您的复选框值之间存在一对多的关系。

答案 3 :(得分:1)

==编辑#3 == 更新了ERD,能够存储自由格式答案,还将patient_reponse_option链接到question_option_link表,以便使用正确的选项上下文保存患者响应(我们知道响应也是哪个问题)。我很快就会发布一些问题。

enter image description here

==编辑#2 ==

使用表单数据

更新了ERD

enter image description here

==编辑#1 ==

对你的问题的简短回答是否定的,400列不是正确的方法。作为替代方案,请查看以下架构:

enter image description here

==原创==

根据您最近的编辑,您需要合并数据透视表。枢轴表打破了'患者'和'选项'之间的M:M关系,例如,许多患者可以有很多选择。为此,您不需要包含400列的表,只需要包含上述数据透视表。

示例模式:

// patient table
tableName: patient
id: int(11), autoincrement, unsigned, not null, primary key
name_first: varchar(100), not null
name_last: varshar(100), not null

// Options table
tableName: option
id: int(11), autoincrement, unsigned, not null, primary key
name: varchar(100), not null, unique key

// pivot table
tableName: patient_option_link
id: int(11), autoincrement, unsigned, not null, primary key
patient_id: Foreign key to patient (`id`) table
option_id: Foreign key to option (`id`) table

使用此模式,您可以拥有任意数量的“选项”,而无需向患者表添加新列。如果您有大量的行,那么如果您必须运行alter table add column命令,则会破坏您的数据库。

我在数据透视表中添加了一个id,所以如果你需要处理单个行,它们将更容易使用,而不必知道patient_id和option_id。