数据库设计 - 将多个报告类型保存在一个表或多个表中

时间:2014-03-18 17:32:11

标签: php mysql database

我已经阅读了以下问题的答案,我相信他们指出了两个不同的答案:

Database Design: Multiple tables vs a single table

MySQL Question - How to handle multiple types of users - one table or multiple?

我的数据库:MySQL 我的语言:PHP 我的问题:我有4个报告要保存在数据库中(将来可能更多)。每个报告的输入都不同于另一个报告。我为每个人创建了一个不同的模块。我试图通过创建一个表来存储公共列(createddate,createdby,reportnumber,title等)来使用面向对象的设计。但是,我最终会得到很多代码,这些代码根据所使用的报告以及其他参数来确定要查看的表。基本上它似乎变得越来越大,因为我在每个模块中使用了大部分相同的代码,并且该报告需要确切的表和列名称。当然,我遇到了这个组合表中至少需要2列的列,这些列对于某些报告而言是NULL值而不是其他报告。

上述链接中的一个答案是创建许多表(多对多),而另一个表示有一个公共表,其中包含特定用户的多个特定表(在我的情况下为报告)。

除非我误解了我正在阅读的内容,否则很可能就是这样。

我的问题:我应该为每个报告创建单独的表,并在代码中具有类似的查询和表设置,或者为所有报告创建一个主公用表,并具有查询数据库并列出表但需要具有的代码许多变量传入或能够查找所需的表/列/路径/标题信息?

编辑2: 对不起困惑

这是我第一次拥有的

数据库表

abc_reports: abc_id, site, system, country, reportnumber, title, createddate, statusid (no duedate)
abc_details: abcdetails_id, abc_id, abc_date, abc_time, location, description, actions
abc_qa: abcqa_id, abc_id, near_miss, opp_improv, level

def_reports: def_id, country, reportnumber, title, createddate, duedate, statusid (no site/sytem, but added duedate)
def_details: defdetails_id, def_id, jobnumber, type, partnumber, part_descrip, serial_num
def_qa: defqa_id, def_id, major, disposition, rep_required, dispo_descrip, dispo_date

xyz_reports: xyz_id, site, system, country, reportnumber, title, createddate (no statusid or duedate)
xyz_details: xyzdetails_id, xyz_id, customer, workgroup, contract_num

网页布局: ABC报告:报告说明,添加新ABC报告的表格,显示最后几个报告的摘要表(html),其中包含创建日期,创建者,报告编号,标题,状态,国家和网站的列标题

DEF报告:报告说明,添加新DEF报告的表单,摘要表(html)显示最后几个报告,其中包含创建日期,创建者,报告编号,标题,状态,截止日期和列标题的列标题国家

XYZ报告:报告说明,添加新XYZ报告的表单,显示最后几个报告的摘要表(html),其中包含创建日期,创建者,报告编号,标题,国家和网站的列标题

SQL查询和html表格布局将专门针对每个报告进行定制。

看到我将使用非常相似的查询并显示非常相似的表,我选择删除“_reports”表并替换为一个表“reports” 所以现在表格是这样的:

reports: report_id(auto-increment), site, system, country, reportnumber, title, createddate, etc
reportstatus: report_id(inserted after new report on reports table), statusid, assignedto, duedate, reviewed, declined, etc

abc_details: abcdetails_id, abc_id, abc_date, abc_time, location, description, actions
abc_qa: abcqa_id, abc_id, near_miss, opp_improv, level

def_details: defdetails_id, def_id, jobnumber, type, partnumber, part_descrip, serial_num
def_qa: defqa_id, def_id, major, disposition, rep_required, dispo_descrip, dispo_date

xyz_details: xyzdetails_id, xyz_id, customer, workgroup, contract_num

现在,网页布局需要在报告表中搜索摘要信息,但现在必须查找报告编号,其前缀与用户正在查看的模块相匹配。 所以我创建了一个函数,为每种类型的报告返回一个变量数组(在SQL查询中为'use_due_date'布尔值,'use_status_id'为布尔值,此特定报告的详细信息网页的路径,报告名称(ABC或DEF,等),特定表的SQL连接语句等。 只要用户查看报告模块,此功能就会被现在的通用摘要表调用。

以下是一个示例:

$sSQL  = "SELECT ";
$sSQL .= "r.reportid, ";
$sSQL .= "r.reportnumber, ";
$sSQL .= "r.title, ";
if ($arrModValues["siteused"]) { $sSQL .= "r.siteid, "; }
$sSQL .= "r.createddate, ";
$sSQL .= "rs.statusid, ";
if ($arrModValues["duedateused"]) {
    $sSQL .= "rs.duedate, ";
    $sSQL .= "rs.duedate < CURDATE() AS is_pastdue, ";
    $sSQL .= "rs.duedate <= CURDATE() + 7 AS is_almostdue, ";
}

$sSQL .= "rs.reviewed, ";
$sSQL .= "rs.declined, "
$sSQL .= "rs.finalized, ";
$sSQL .= "r.createdby, ";
$sSQL .= "rs.assignedto ";
$sSQL .= "FROM reports r ";
$sSQL .= "LEFT JOIN reportstatus rs ON r.reportid = rs.reportid "
$sSQL .= get_joining_statement($sMod);
$sSQL .= "WHERE ";
$sSQL .= "moduleid = '$sMod' AND ";
$sSQL .= "countryid='$sCountry' ";
$sSQL .= "ORDER BY ";
$sSQL .= "createddate ";

$sSQL .= "DESC";


// get the query results

$arrResults = query($sSQL);

Then the common table:
if ($arrResults) {

// get headers for header table

$arrHeaderDef = array();

$arrHeaderDef[]     = "Created";
$arrHeaderDef[]     = "Report Number";
$arrHeaderDef[]     = "Title";
if ($arrModValues["siteused"]) { $arrHeaderDef[] = "Site"; }
$arrHeaderDef[]     = "Status";
if ($arrModValues["duedateused"]) { $arrHeaderDef[] = "Due Date"; }

$arrHeaderDef[]     = "Disposition";
$arrHeaderDef[]     = "Created By";
$arrHeaderDef[]     = "Assigned To";
$arrHeaderDef[]     = $arrModValues["coltitle"];
$arrTable[] = $arrHeaderDef;

依旧......

我希望这不会让我的问题更加复杂。如果你想指出任何编程设计错误,请随意。

所以最大的问题是:我是否应该单独离开原始表并为每个模块(报告)创建类似但特定的PHP / SQL代码,如上面第一个链接中的答案所示或者我是在正确的路径上尝试结合报告的常见元素并创建常见查询和表格布局,如上面第二个链接的答案建议?或者都不是?设计这个系统的更好方法是什么?

再次感谢你。对不起,它太长了,而且很混乱。

谢谢你, 萨姆

1 个答案:

答案 0 :(得分:0)

您打算收到多少份报告?

我曾经遇到过同样的问题并通过添加一个非常大的表来解决它,所有列都可能显示出来。根据事件,很多列都会变空,但一次查询一个表就不那么令人头痛了。但为了使其可扩展,我最终使用参考表每月自动创建一个新表,因为最常查询的数据将来自当前月份。

reftable
id, sekid, table (table would refer to which table below)

table201401
sekid,column,column,etc,etc,etc

table201402
sekid,column,column,etc,etc,etc

这样可以在设置查询月份后轻松搜索每个列。但是,根据您的数据使用,就像它可以搜索和排序等等。存储为json字符串时可能会获得大量数据。就像在一列中存储具有值的数组一样。不是非常易于搜索和排序,但如果您需要打印出来作为参考,那么可以节省大量空间。

在我的情况下,我最终做我所做的主要原因只是数据操作在当月是极端的。下个月的上个月表仅用作参考,偶尔会更新。

每个案例都有它需要关注的特殊需求,并且总是很好地思考大而且可扩展。找到可管理和可接受的平衡。我希望这篇文章能给你一些指导。我想我会分享它,因为我记得自己曾经问过同样的问题。