特定于类别字段的数据库布局

时间:2011-02-25 01:45:32

标签: mysql database-design

我正在为市政府呼叫中心制定服务请求系统。公民呼入,呼叫中心代理将他们的请求输入网络表格,然后传输到相应的市政机构。我的问题属于网络表单。

解释这个的最好方法是举个例子。如果来电者A 正在调用报告涂鸦,则在代理从类别列表中选择“涂鸦”后,我希望其中包含以下内容的单独字段:

  • 涂鸦的位置/地址
  • 覆盖它所需的油漆颜色
  • 梯子有必要吗? (等)

如果来电者B 打电话报告被遗弃的车辆,则提供的字段应为:

  • 车辆的位置/地址
  • 制造/车型
  • 车牌号码
  • 车辆颜色(等)

显然,位置/地址等字段对于任何类别的呼叫都是通用的,但其他字段不是,并且通常仅与一种类型的呼叫相关。所以问题是如何布局我的数据库以适应这个?

当然,我想到的一个想法就是在调用表中包含所有这些字段,并以某种方式指定哪些字段与哪种类型的调用有关,其余字段为null(license_plate为null涂鸦投诉等)。但是字段的数量肯定会加上这个选项。

我的另一个想法是拥有单独的表,即graffiti_calls表,并在那里定义字段,尽管某些类别的调用不需要自定义字段(例如有人打电话来获取电话数)。

最后,我认为实现这一目标的更复杂的方法是使用category_questions表格id, category_id, questionfield_responses表格id, call_id, question_id, response。这个选项似乎是最通用的,但也是最复杂的。

最好的方法是什么? 请注意,我有PHP / MySQL的经验;这更像是一个概念问题。 提前谢谢!

编辑:所以我在第3个选项中玩了一下,然后提出了this layout。如果你认为这可以通过更好的方式实现,我仍然愿意接受建议。

4 个答案:

答案 0 :(得分:1)

鉴于您要搜索变量字段,可接受的结构将是具有包含所有全局字段的主表,例如身份证,地址,日期等......

然后是一个具有以下格式的属性表:

`id`, `field_name`, `field_value`

因此,对于涂鸦示例,您可以在主表中使用id=1, problem_type=graffiti, address='main street ...'

然后在属性表中你有几行:

id=1, field_name=paintcolor, field_value=blue
id=1, field_name=ladder, field_value=FALSE
etc...

这将允许您搜索变量字段。

为了存储问题,我有一个映射了problem_type,field_name,question_text的表。一个示例条目是:

graffiti, ladder, 'Is a ladder required?'
graffiti, paintcolor, 'What paint color is required?'
etc...

您可以根据需要对其进行扩展,并希望在此表中添加输入类型等额外字段,以便您可以智能地生成html表单,例如:对于梯形图,您可能只需要一个带有是/否的选择框,您可以在问题表中添加列,指定输入类型,符合条件的值,验证正则表达式等...这一切都取决于您想要的精细程度得到。

答案 1 :(得分:0)

您可以拥有第二个包含子类的表,其中的条目是描述以及它所属的主类的名称。如果你想变得更加漂亮,你总共可以拥有3张桌子。

表1是您的“主”故障条目,它将包含主类别和子类别的外键ID。

表2将是您的主类别表,其中包含PK和类别说明。

表3将是子类别表,其中包含PK和主类别表的外键,以及子类别描述。

答案 2 :(得分:0)

你已经想出了所有三种可能的型号。不幸的是,你的问题没有明确的答案。

后一种方法(称为EAV)通常用于frequently changed的结构。

顺便说一句,我认为只使用一个表("答案")和问题的字符串键就可以了。

答案 3 :(得分:0)

鉴于每种类型的请求都有数据完整性要求,我会设置一个子类型架构:

Create Table Request
    (
    Id ... not null Primary Key
    , RequestDate datetime not null
    , ...
    )

Request表中的列将普遍适用于所有类型的请求。然后,对于每种类型的请求,您将以一对一关系创建单独的表。如果可能,您希望尝试将具有相似属性的请求组合在一起。

Create Table DefacementRequest
    (
    RequestId ... not null Primary Key 
    , Location ... not null
    , Description ... not null
    , RequiredEquipment ...
    , ...
    , Constraint FK_DefacementRequest_Request
        Foreign Key ( RequestId )
        References Requests( Id )
    )

Create Table MotorVehicleRequest
    (
    RequestId ... not null Primary Key 
    , Make ... not null
    , Model ... not null
    , VIN ...
    , Color ...
    , Location ...
    , ...
    , Constraint FK_DefacementRequest_Request
        Foreign Key ( RequestId )
        References Requests( Id )
    )

每种类型的请求都有自己的必需数据集,这足以让您使用单独的表来强制执行这些类型的规则(例如,车辆请求必须具有VIN或品牌和型号)。如果您尝试使用EAV,则无法在数据库中强制执行这些规则,并且会根据特定类型的请求生成非常繁琐的报告。