我有一张表Student
,其中包含字段
学生表(每位学生一条记录)
student_id
Name
Parent_Name
Address_line1, Address_line2, Addess_line
Photo_path
Signature_file_path
Preferred_examcity_choice1,Preferred_examcity_choice1, Preferred_examcity_choice3
Gender
Nationality
.
.
.
我通过网络界面在注册表单填写中插入此表。
现在Web界面中还有一个模块用于更新学生数据,每次更新请求时我都会更新student
表记录并在student_data_change_request
中插入新条目。学生可以多次更改记录。
student_data_change_request
request_id(auto_incr PK)
old_name
new_name
old_photo_path
new_photo_path
old_signature_file_path
new_signature_file_path
现在出现问题,之前的学生可以更改很少的字段,现在客户希望允许候选人更新更多字段(大约20个字段)并添加old
和new
列对于相应的列不是优雅和首选(我猜),我将最终创建40列以跟踪20列。那我该如何重新设计我的桌子呢?欢迎提出建议。
答案 0 :(得分:3)
一种方法是使一个名为(table)_xx的影子表具有相同的列,时间,日期,更新/插入/删除标志,用户或任何其他参考完整性。设置触发器,以便在发生任何事情时从源更新该表。
如果您有真正的业务需求需要历史记录,那么请正确执行这些需求,但这种模式非常适合作为一般审计,调试和取证工具。
自动化/脚本也非常容易,因为您只是从数据库元数据中生成它。
答案 1 :(得分:0)
通常历史表如下:
request_id
column_name
old_value
new_value
dt
request_id 和 column_name 是主键。更新学生表时,会在每个更新列的 student_data_change_request 中插入新条目。
<强>被修改强>: 另一种方式:
request_id
value_type
name
photo_path
signature_file_path
...
并插入带有旧值的第一个条目和带有新值的第二个条目。 Colum value_type 标记为旧或 new 。
答案 2 :(得分:0)
我宁愿只有一个表,还有一个用于生效日期的列。然后,只为每个student_id选取最新行的视图将成为您的第一个“表”。如果由于某种原因你必须并排显示“当前”和“最近更改”的值,那就是另一种观点。
答案 3 :(得分:0)
与往常一样,这一切都取决于您打算如何使用数据。
我在这些案例中的强烈偏好是@mathguy建议的解决方案 - 在主表设计中嵌入时间概念。这可以让您提出问题&#34; 1月1日这个学生的地址是什么?&#34;或者#2;谁在2月12日签名x?&#34;。
如果您必须报告或执行反映任何时间点状态的业务逻辑,则此设计非常有效。例如,如果您必须报告某个学期特定地址中有多少学生,您想知道这些记录何时有效。
但并非所有应用都关心&#34;时间&#34; - 有时候,你只想拥有一个审计表,这样就可以追踪出现异常时发生的事情。
在这种情况下,@ loztinspace的解决方案很有用 - 但根据我的经验,这会迅速升级为更多工作,因为那些想要检查审计记录的人可以或不应该访问您的SQL提示生产环境。