Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 数据库设计-类别和子类别_Sql Server_Database_Categories_Database Performance - Fatal编程技术网

Sql server 数据库设计-类别和子类别

Sql server 数据库设计-类别和子类别,sql-server,database,categories,database-performance,Sql Server,Database,Categories,Database Performance,我需要在一些类似于golden pages的东西上实现分类和子分类 假设我有下表: 类别表 我有两个选项来编码子分类 选项1-子类别Id仅在类别内唯一: 子类别表 选项2-子类别Id整体上是唯一的: 子类别表 选项2听起来似乎更容易从表中获取行 例如:从tblBiz中选择BizTitle,其中SubCatId=170 而使用选项1,我必须写下如下内容: SELECT BizTitle FROM tblBiz WHERE CatId = 30 AND SubCatId = 170 SELECT

我需要在一些类似于golden pages的东西上实现分类和子分类

假设我有下表:

类别表 我有两个选项来编码子分类

选项1-子类别Id仅在类别内唯一: 子类别表 选项2-子类别Id整体上是唯一的: 子类别表 选项2听起来似乎更容易从表中获取行 例如:
从tblBiz中选择BizTitle,其中SubCatId=170

而使用选项1,我必须写下如下内容:

SELECT BizTitle FROM tblBiz WHERE CatId = 30 AND SubCatId = 170
SELECT BizTitle FROM tblBiz WHERE ParentId = 3 AND CategoryId = 11
i、 例如,包含额外的

然而,选项1更容易手动维护(当我需要更新和插入新的子类别等时),而且我认为它更令人赏心悦目


有什么想法吗?选项2在效率方面值得麻烦吗?是否有与此常见问题相关的设计模式?

我将使用此结构:

ParentId, CategoryId, Title
null, 1, Home
null, 2, Business
null, 3, Hobbies
1, 4, Gardening
1, 5, Kitchen
1, 6, ...
2, 7, Development
2, 8, Marketing
2, 9, ...
3, 10, Soccer
3, 11, Reading
3, 12, ...
详细内容:

  • 只使用一个表,引用自身,这样您就可以拥有无限的类别深度
  • 使用技术ID(使用
    IDENTITY
    或类似工具),这样您可以拥有10个以上的子类别
  • 如果需要,为类别编号添加一个人类可读的列,作为单独的字段
只要您只使用两个级别的类别,您仍然可以这样选择:

SELECT BizTitle FROM tblBiz WHERE CatId = 30 AND SubCatId = 170
SELECT BizTitle FROM tblBiz WHERE ParentId = 3 AND CategoryId = 11

SQL server的新的
hierarchyid
功能看起来也很有前途:


我不喜欢嵌套集模型的哪些方面:

  • 在嵌套集模型中插入和删除项是一件非常复杂的事情,需要昂贵的锁
  • 如果将
    parent
    字段与外键约束结合使用,则可以轻松创建禁止的不一致。
    • 如果
      rght
      低于
      lft
    • 如果在多个
      rght
      lft
      字段中出现一个值,则可能会出现不一致
    • 如果您创建间隙,可能会出现不一致
    • 如果创建重叠
  • 在我看来,嵌套集模型更复杂,因此不容易理解。当然,这是绝对主观的
  • 嵌套集模型需要两个字段,而不是一个字段,因此会占用更多的磁盘空间

我建议选择选项1-保持子类别在类别中唯一。假设我有两类不相关的项目:

  • 果实
  • 颜色
对于每一个,我想要一个子类别

  • 果实

    • 苹果
    • 橙色的
  • 颜色

    • 白色的
    • 橙色的
请注意,橙色是每个类别中的一个子类别。虽然名称相同,但其功能非常不同。(让我们不要讨论橙色水果是橙色的可能性)

有了这个设计,如果有人改变了主意,想把橙色改名为橙色,很好。很容易改变,而不会影响颜色下的橙色子类别


如果用户界面的构建方式是营销可以控制颜色的子类别,而生产可以控制水果的子类别,那么这种设计将允许营销在不跨过生产子类别的情况下处理它们的子类别。

管理分层数据有一些方法。最重要的方法之一是
Nested Set Model
。用于实现。甚至像Joomla这样的一些内容管理系统也使用这种结构


更新2020:由于这篇文章中有一些考虑因素,我应该说,现在我更喜欢邻接列表模型而不是嵌套集模型,因为这种方式的复杂性更低。也是为了实现。

我认为你必须使用选项2为categoryid为PK的类别创建一个表,并创建另一个选项卡le SubCategory,其中SubCategory ID为PK,categoryid为FK。在这种情况下,每次我们都必须应用自连接以获得具有SubCategory的类别是否可行way@tinka如果您只使用两个深度级别,您仍然可以轻松选择(请参阅我的更新)我无法下定决心。但我采纳了你的建议。谢谢你们的帮助。你真的应该了解嵌套集模型。这个答案并不总是解决此类问题的最佳方法。@slartidan事实上,一天下来,这是个人喜好的问题。
SELECT BizTitle FROM tblBiz WHERE ParentId = 3 AND CategoryId = 11