【问题标题】:Database Design - Multiple report types kept in one table or multiple tables数据库设计 - 多个报表类型保存在一个表或多个表中
【发布时间】:2014-04-24 13:43:21
【问题描述】:

我已阅读以下问题的答案,我相信它们指向两个不同的答案:

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 代码,就像上面第一个链接中的答案所建议的那样,或者我是否通过尝试走在正确的道路上结合报告的共同元素并创建共同的查询和表格布局,就像上面第二个链接的答案所暗示的那样?或者两者都不是?设计这个系统的更好方法是什么?

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

谢谢你, 山姆

【问题讨论】:

  • 我会心血来潮地说这取决于您使用的数据类型(在我看来)。你能提供一些样本“报告”吗?一些表格结构适合一种类型的报告,而其他报告可能需要更复杂的内容。
  • 听起来您的数据库需要存储有关事件和问题的信息。 (与报告无关。)将一些 CREATE TABLE 语句粘贴到您的问题中以澄清问题。

标签: php mysql database


【解决方案1】:

您打算获得多少份报告?

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

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 字符串可能会导致很多数据丢失。就像在单个列中存储具有值的数组。不是很容易搜索和排序,但如果您只需要打印出来作为参考,就可以节省大量空间。

就我而言,我最终做我所做的事情的主要原因只是本月的数据操作将是极端的。下个月的上个月表仅作为参考,偶尔更新。

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

【讨论】:

    猜你喜欢
    • 2010-10-26
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多