sql - 查找表有多重要?

标签 sql mysql database-design

我编写的许多应用程序都使用了查找表,因为这正是我学习的方式(规范化等)。问题是我所做的查询通常因此更加复杂。他们经常是这样的

获取所有仍然打开的帖子

"SELECT * FROM posts WHERE status_id = (SELECT id FROM statuses WHERE name = 'open')"

很多时候,查找表本身很短。例如,可能只有 3 种左右的不同状态。在这种情况下,是否可以在应用程序中使用常量左右来搜索某种类型?就像是

获取所有仍然打开的帖子
"SELECT * FROM posts WHERE status_id = ".Status::OPEN

或者,如果我不使用外部 ID,而是将其设置为枚举并对其进行查询,该怎么办?

谢谢。

最佳答案

如果您仅限于 PostGreSQL(不完全符合 SQL 标准)等免费软件,或者您正在考虑使用 SQL(即符合 SQL 标准)和大型数据库,那么答案在一定程度上取决于您。
在 SQL 兼容中,Open Architecture数据库,其中有许多应用程序使用一个数据库,许多用户使用不同的报告工具(不仅仅是应用程序)来访问数据,标准、规范化和开放架构要求很重要。
尽管人们试图改变“规范化”等的定义以适应他们不断变化的目的,规范化(科学)并没有改变。

  • 如果您有数据值,例如 { Open; Closed; etc } 在数据表中重复,即数据重复 ,一个简单的归一化错误:如果你的那些值发生变化,你可能不得不更新数百万行,这是非常有限的设计。
  • 此类值应标准化为引用表或查找表,并带有简短的 CHAR(2) PK:
    O  Open
    C  Closed
    U  [NotKnown]
    
  • 数据值 { Open;Closed;etc } 不再在数百万行中重复。它还可以节省空间。
  • 第二点是易于更改,如果Closed改为 Expired ,再次,需要更改一行,并反射(reflect)在整个数据库中;而在未规范化的文件中,需要更改数百万行。
  • 添加新的数据值,例如。 ( H,HalfOpen ) 那么只是插入一行的问题。

  • Open Architecture术语,Lookup 表是一个普通表。它存在于 [SQL 兼容] 目录中;只要FOREIGN KEY关系已经定义,报表工具也可以找到。
  • ENUM是一个非 SQL,不要使用它。在 SQL 中,“枚举”是一个查找表。
  • 下一点与 key 的意义有关。
  • 如果 Key 对用户没有意义,那么可以使用 { INT;BIGINT;GUID;etc或任何合适的;不要递增编号;允许“间隙”。
  • 但是如果 Key 对用户有意义,就不要使用无意义的数字,使用有意义的 Relational Key。

  • 现在有些人会开始讨论 PK 的持久性。这是一个单独的观点。是的,当然,始终为 PK 使用稳定值 (不是“不可变的”,因为不存在这样的东西,并且系统生成的键不提供行唯一性)。
  • { M,F } 不太可能改变
  • 如果您使用过 { 0,1,2,4,6 },不要改变它,你为什么要改变它。这些值应该是没有意义的,记住,只有一个有意义的 Key 需要改变。
  • 如果您确实使用有意义的键,请使用简短的字母代码,开发人员可以轻松理解(并从中推断出长描述)。只有当您编码 SELECT 时,您才会欣赏这一点。并意识到您不必JOIN每个查找表。高级用户也是,欣赏它。

  • 由于 PK 是稳定的,尤其是在查找表中,您可以安全地编码:WHERE status_code = 'O' -- Open您不必JOIN查找表并获取数据值Open ,作为开发人员,您应该知道查找 PK 的含义。

  • 最后,如果数据库很大,并且除了 OLTP 之外还支持 BI 或 DSS 或 OLAP 功能(正确规范化的数据库可以),那么查找表实际上是一个维度或向量,在 尺寸事实 分析。如果它不存在,则必须添加它以满足该软件的要求,然后才能安装此类分析。
  • 如果从一开始就对数据库执行此操作,则以后不必升级它(和代码)。

  • 你的榜样
    SQL是低级语言,因此很麻烦,尤其是在JOINs的时候。 .这就是我们所拥有的,所以我们只需要接受负担并处理它。您的示例代码很好。但是更简单的形式可以做同样的事情。
    报告工具将生成:
    SELECT p.*,
           s.name
        FROM posts  p, 
             status s
        WHERE p.status_id = s.status_id 
        AND   p.status_id = 'O'
    
    另一个例子
    对于银行系统,我们使用有意义的短代码(因为它们有意义,我们不会随着季节改变它们,我们只是添加它们),给定一个查找表,例如(精心选择,类似于 ISO 国家代码) :
    Eq   Equity
    EqCS Equity/Common Share
    OTC  OverTheCounter
    OF   OTC/Future
    像这样的代码很常见:WHERE InstrumentTypeCode LIKE "Eq%"GUI 的用户将从显示的下拉列表中选择值
    { Equity/Common Share;Over The Counter },
    不是 { Eq;OTC;OF }, 不是 { M;F;U }.
    没有查找表,您无法在应用程序或报告工具中执行此操作。

    关于sql - 查找表有多重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4824024/

    相关文章:

    php - 通过匹配日期查询获取详细信息

    sql - 关于传感器/读取/警报数据库设计的意见

    MySQL数据库复合fk设计考虑

    sql - Snowflake 使用 flatten 进行数组展平返回未知函数

    sql - 在查询中为 'OR' 运算符创建索引

    python - isnull(col1,col2) 在 Pandas 中等效

    mysql - SQL DELETE 从多个表

    php - 使用 php 将 'input type text' 作为日期插入 mysql 数据库

    php - 注册页面未注册用户

    sql - 规范化和复合表结构