代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Meyer

在开发新的SQL数据库时,常见的陷阱是什么?

  •  3
  • Jeffrey Meyer  · 技术社区  · 7 年前

    我知道,我非常不喜欢“捕捉所有调查”类型的问题,但我想不出更好的方法来找出我想知道的东西。在数据库开发的世界里,我是非常环保的,我只处理过少数只与数据库交互的项目,而不必从头开始创建一个新的项目。然而,事情发生了变化,现在我面临着创建自己的数据库。

    到目前为止,我已经创建了我需要的表,并添加了我认为需要的列,包括许多关系的任何链接表和一对多关系的列。关于这个问题我有一些具体的问题,但我觉得与其仅仅回答这些问题,不如问一些我甚至不知道的问题,我现在应该解决这些问题,而不是6个月后,当我们有一个填充的数据库和使用它的客户机工具时。

    首先,我的数据库中的问题让我意识到我还不够了解:

    1. 当对引用的表进行更改时,如何确保多对多链接表和一对多列是最新的?我会遇到什么问题?
      • 我正在对各种文本字段使用nvarchar(n)和nvarchar(max)。我应该改用varchar等价物吗(我已经读到使用nvarchar可能存在性能风险)?除了使用固定长度的字符数组保存可变长度的信息之外,是否还有其他关于数据类型选择的问题?关于如何选择适当的数据类型有什么规则吗?
      • 我用 int 对于 ID 每个表的列,它是除链接表之外的所有表中的主键(其中我有两个主键,即 身份证件 引用表行的s)。此ID设置为标识。这种方法有缺陷吗?
      • 我已经为诸如单元类型和状态之类的事情创建了元数据表,但是我不知道这是否是正确的事情。您应该为枚举列表之类的东西创建新表,还是有更好的方法?

    我知道数据库是复杂的,是许多有价值的大部头的主题,但我怀疑你们中的许多人有一些技巧和窍门来增加这样的阅读材料(尽管基本阅读技巧也是受欢迎的)。

    社区维基是由于这些帖子的主观性质。抱歉,如果这是一个副本,我已经搜索了很多类似的东西,但是找不到。 this one is certainly related . 谢谢。

    更新

    我刚刚发现 this question 在迂回的道路上非常相似。

    8 回复  |  直到 17 年前
        1
  •  3
  •   Karim Agha    9 年前
    1. 不正规化
    2. 不使用归一化
    3. 尝试从一开始就实现非规范化架构

    严肃地说:

    1. 外键将不允许从父表中删除或更新。或者它们可以级联。

    2. 尽可能小:2个最近的SO问题 datatypes 和 (n)varchar

    3. 可能不可移植,您的“自然密钥”(称为“产品名称”)仍然需要唯一的约束。否则没有,但请记住,标识列是 surrogate key “

    编辑:假设您希望用列“水果ID”和“水果名称”来存储水果。你无法限制“苹果”或“橙色”的出现,因为尽管这是你的“天然钥匙”,但你使用的是替代钥匙(水果ID)。所以,为了保持完整性,您需要对水果名有一个唯一的约束。

    1. 不确定或你的意思,对不起。 编辑:不要这样做。叶奥尔德 One true lookup table “主意。
        2
  •  2
  •   kmarsh    17 年前

    我将以一些模糊的概括性回答你的主观问题。:)

    设计数据库最常见的陷阱是任何编程解决方案的相同陷阱,而不是完全理解正在解决的问题。对于数据库,它理解数据的性质。它有多大,它来来去去去,它必须遵守什么业务规则。

    这里有一些问题需要考虑。

    最频繁更新的是什么?保持该表的写入锁定是否会锁定查询?它会成为一个热点吗?如果您不理解读写比率,即使是一个看起来很正常的模式也可能是一个糟糕的执行者。

    您的外部接口需要什么?我曾经参与过这样的项目,“那另一个系统”的虚线几乎破坏了整个项目,因为实施它被延迟到其他一切都到位,也就是说,其他一切都是不灵活的。

    还有其他的潜台词要求吗?我最喜欢的是日期敏感。所有的数据都在那里,你的报告很漂亮,老板看了看然后问,数据什么时候改变了?是谁干的,什么时候干的?数据库应该跟踪自身及其用户,还是只跟踪数据?你的前端会为你做吗?

    只是一些需要考虑的事情。

        3
  •  1
  •   JeeBee    17 年前

    听起来你已经很好地掌握了你要做的事情,事实上,没有一条真正的途径去做数据库。

    您是否为分层对象设置了级联(即,在数据库中对象的“head”处进行一次删除,将删除与该条目相关的表中的所有条目)?

    您的链接表和1:n列应该是外键,因此不必担心数据是否更改。这里的“两个主键”是指索引吗?

    至于元数据表,我以前做过,但没有做过。带有SQL注释的单个char状态可以满足有限的一组状态,但是超过一定的数量,或者您可以考虑在将来添加更多的状态,您可能希望引用另一个元数据表,或者一个char(8ish)。例如,我见过用户表有“normal”、“admin”、“super”、“guest”等用户类型,这可能是1、2、3、4、5 fkeys到“user type”表,但是有了这样一个限制的枚举,这是否重要?其他人有一个权限表(用户可以做的事情的布尔值)来代替-很多方法来剥猫皮。

        4
  •  1
  •   jandersson    17 年前

    您可能会在这些幻灯片中找到一些有用的内容: [ http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back][1]

        5
  •  1
  •   JoeCool    17 年前

    我也是数据库设计的初学者,但我发现这个在线教程非常非常有帮助:

    Database design with UML and SQL, 3rd edition

    作者以非常清晰的方式解释了数据库的所有基本设计方面。在我找到这个在线指南之前,我做了很多维基百科关于规范化的阅读。虽然这有帮助,但作者解释了完全相同的东西(至少通过第三种正常形式),但以一种更容易阅读的方式。它也能解决你所有的问题。

        6
  •  0
  •   A-K    17 年前
        7
  •  0
  •   Dave W. Smith    17 年前

    除了不规范化之外,我看到的一个常见问题是 超标引 ,在进行性能度量之前,必须考虑到生产中的读与写混合。

    添加一个索引来加快查询速度真的非常非常容易,而且当有几个索引在插入或更新过程中得到更新时,很难确定要删除哪个索引。

    中间立场是寻找明显的二级索引(例如,对于大表上的常见、频繁的按名称查找),将其他候选索引推迟到有合理的性能测试为止。

        8
  •  0
  •   Darth Continent    17 年前

    除此之外,不使用主键,不考虑是否将使用索引视图(并相应地设计表;我曾经不得不在我的站点上删除并重新创建一个大表,将其ansi_-null属性更改为on,以便我可以在索引视图中使用它),而是使用索引。