MySQL规范化或非规范化

问题描述 投票:1回答:5

我正在构建一个PHP应用程序,以使用客户数据预填充第三方PDF帐户表单,并且陷入数据库设计的困境。

当前表单大约有70个字段,这似乎太多了,无法设置为单独的列,尤其是根据客户所需的帐户类型,某些字段(即公司/信托信息)不相关。

我已经尝试进行标准化,但似乎会有很多联接,并且还需要多个子查询来查询多个地址。

这还意味着要进行大量额外的查询,以便在更新时检查行是否存在,以决定脚本是否需要执行INSERT,DELETE或UPDATE,而如果全部在一行中,则基本上只是每次更新。

不确定是否有帮助,但这是大多数字段的列表:

id,account_type,account_phone,account_email,account_designation,account_adviser,account_source,account_complete,account_residential_unit_number,account_residential_street_number,account_residential_street_name,account_residential_street_type,account_residential_suburb,account_residential_state,account_residential_postcode,account_postal_unit_number,account_postal_street_number,account_postal_street_name,account_postal_street_type,account_postal_suburb,account_postal_state,account_postal_postcode,个人_1_标题,个人_1_名字,个人_1_中间名,个人_1_姓氏,个人_1_dob,个人_1_职业,个人_1_电子邮件,个人_1_电话,personal_1_unit_number,individual_1_street_number,individual_1_street_name,individual_1_street_type,individual_1_suburb,individual_1_state,individual_1_postcode,个人_2_标题,个人_2_名字,个人_2_中间名,个人_2_姓氏,个人_2_dob,个人_2_职业,个人_2_电子邮件,个人_2_电话,personal_2_unit_number,individual_2_street_number,individual_2_street_name,individual_2_street_type,individual_2_suburb,individual_2_state,individual_2_postcode,公司名称,公司日期,company_unit_number,company_street_number,company_street_name,company_street_type,company_suburb,company_state,company_postcode,trust_name,trust_date,结算银行,结算帐户,结算b​​sb

最多需要处理大约200,000个应用程序,并且一旦数据进入数据库,就不会经常更改(如果有的话-不确定是否相关吗?

因此,即使只是只是进一步研究的名称或主题,实际上也只是想找出最明智的设计方法。

mysql database-design database-normalization denormalization
5个回答
2
投票

通常来说,您可以将数据库分为两大类:

  1. OLTP系统

    在线交易处理系统通常需要大量写入操作,即与数据读取相比要进行大量更新。该系统通常是所有范围的业务用户(例如,数据捕获,管理等)使用的日常应用程序。这些数据库通常被规范化到极致,然后为了某些方面的性能提升而被贬低。

  2. OLAP / DSS系统:

    联机分析处理是通常像系统一样的大型数据仓库的数据库。用于支持诸如数据挖掘,数据多维数据集等分析活动。通常,与OLTP相比,该信息由一组更有限的用户使用。这些数据库通常非常不规范。

请阅读此处,以简要描述这些内容和主要区别。OLTP VS OLAP

关于您的INSERT/UPDATE/DELETE要点,请阅读有关MySQL ON DUPLICATE KEY UPDATE语句的信息,该语句将为您轻松解决该问题。在大多数数据库系统中,此操作称为MERGE操作。

现在我不明白您为什么担心JOINS。我有具有数百万(500 000 000+)行的表,而我与其他表联接的表也很大,并且查询运行非常快。因此,设计数据库以消除联接不是一个好主意。

我的建议是:

如果设计OLTP系统,则尽可能进行标准化,然后在需要的地方进行标准化以提高性能。对于OLAP系统,请查看星型模式等,甚至不必先对其进行规范化。哦,大多数OLAP系统通常都将OLTP系统用作数据源。


1
投票

通常,我先进行归一化,然后再对性能进行归一化。但是

[如果我没有太多验证可做,例如有效地址,个人重复

而且我不想为另一版本的表单重用部分数据,例如选择一个现有的个人,姓名和地址等

[我也不想分析它,例如找到弗雷德·博格斯的所有提及

而且我的用户很乐意输入所有一种表格(我不会)

然后,我将一开始就使用非规范化。

如果您进行归一化,然后进行归一化(如果需要的话)是微不足道且风险低的,归一化归一化后的数据通常意味着重复数据删除,这可能确实是痛苦的数据,并且是明智的设计。


1
投票

归一化您的输入,去归一化输出。意思是,对于报表,将数据提取为非规范化格式(如Mongo)并用于查询。或者,创建某种汇总。我发现,使用大型数据集,可以从输入数据中提取报告数据,以实现最佳效率。


0
投票

我发现在非常基本的水平上使用非规范化数据非常痛苦。如果我想统计一下佐治亚州的人口数量怎么办?在您的非规范化结构中,我必须计算ind_1_state = GA或ind_2_state = GA。

我想这还算不错,但是对于那些看到标准化提供的查询简便性的人来说,这是很痛苦的。

规范化为越来越复杂的查询奠定了基础。没有它,您将发现实施更丰富的数据分析变得越来越困难。

规范化还提供了数据库完整性和一致性的基础。如果在一个地方(一列)中出现了所有特定事物(状态缩写),则可以轻松地检查并限制这些值以不允许不存在的代码。

进行标准化的理由不断,但我希望我不加思索。


0
投票

这没什么大不了的-您现在所拥有的只是一个名词汤,您将其挤入一个表格存储鞋盒中,并在每行的开头粘贴了一些ID。

创建某种模式。如果这更像是OLAP,并且您决定采用星型模式,它将具有2-5 NF的维数和2-6 NF的事实维。对于OLTP(或不同的仓库模型),目标是BCNF-6NF。

我会争辩说您在这里甚至没有1NF,将开头的ID粘贴起来并不算是防止重复。因此,即使您想这样做,您无法从这一点开始进行非规范化:)-好的,也许您可​​以将一些逗号分隔的列表放在某个地方,以使事情绝对不在1NF中。

联接是关系数据库的作用,因此不必担心。

© www.soinside.com 2019 - 2024. All rights reserved.