我正在设计一个可能有200K行的新表。 我想确保对此表的查询是有效的。
在过去,我总是给出一行唯一的id,假设这会产生一个索引:
CREATE TABLE [dbo].[Equipment](
[EquipID] [nchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[EquipDescription] [nchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Category] [nchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[id] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
这够了吗? ,我应该设置一个主键。
如果有人有建议,请让他们飞。
T-SQL,SQL2000,
答案 0 :(得分:3)
如果您创建主键或显式创建主键,则只能获得索引。您需要的索引由您的查询决定,只是在列上有索引不会使查询更快,除非您查询或加入该列。
指数也不是没有成本,它们会使您的数据库变大,并且会增加修改表格的成本。
这个article虽然陈旧,但似乎很好地概述了指数。
如果您打算使用数据库获取像Database Systems这样的数据库教科书并阅读它,那将证明无价之宝。找到最有效的索引和查询排列很困难,而试错也不是尝试优化查询的好方法。
答案 1 :(得分:1)
最佳做法是在表格上创建主键。正如@deinst指出的那样,除非您明确创建索引,否则不会获得索引。创建主键是创建索引的一种方法。
[id]列可能是主键的一个很好的候选者。并且,将它作为您的聚簇索引(每个表获得一个聚簇索引)可能是可以的,这是创建主键时的默认值。
您可能希望根据查询表的方式在其他列上创建索引(再次由@deinst指示)。
[EquipID]是表格的自然键。自然键是业务域中的唯一属性。业务人员如何参考每个项目。如果[EquipID]是自然键,您可能希望为此列添加唯一约束或唯一索引,并且您可能希望将其可为空性更改为NOT NULL。
答案 2 :(得分:1)
数据库优化本身就是一门艺术/科学,数据建模也是如此。首先确保您的架构是可靠的并支持您的应用程序。然后,您可以添加索引以提高查询性能。但是,不要根据一些概念做出数据建模选择,即选择会以某种方式使表更快地查询。
1)除了性能之外,所有表都应该有一个主键。您需要能够唯一地识别记录。
2)查询的性能和哪些索引将提高效率取决于查询。如果您在JOIN,WHERE子句或ORDER BY子句中使用列,那么它应该有一个索引。您的主键将自动获取索引,因此请考虑以这种方式使用哪些其他列。在某些情况下,多列索引是最佳选择。
答案 3 :(得分:0)
你应该问自己的第一件事是“'装备'的属性是什么?”一台设备是否可以没有EquipID,描述或类别?如果不是,则不应允许这些列为空。
其次是“唯一定义一件'装备'的东西?”它是EquipID吗?那应该是你的主键。它是EquipID和Category的组合吗?然后,您有一个由两列组成的复合主键。但是,有时候,数据自然不适合在完全关系模型中可以轻松加入的主键。因此,您可以像显示的那样考虑身份ID列 - 这称为代理键。知道默认情况下创建主键会在这些键列上创建聚簇索引。如果你采用代理键方法,那么恕我直言,最好为你的对象的唯一性创建另一个独特的索引(即EquipID)。
就其他索引而言,你应该进一步问自己“我最常要查询哪些列?”也许你会有很多问题,比如“SELECT EquipID FROM Equipment WHERE Category = 3”。这表明Category是索引的一个很好的候选列。
最后,另一个好的经验法则是索引任何外键列 - 它似乎是Category。这会优化您可能执行的任何连接查询。
对此的一个好方法是下面的内容(快速抛出,未经测试):
CREATE TABLE [dbo].[Equipment](
[EquipID] [nchar](20) NOT NULL
,[EquipDescription] [nchar](100) NOT NULL
,[CategoryID] [bigint] NOT NULL
,CONSTRAINT [PK_Equipment] PRIMARY KEY CLUSTERED (
[EquipID] ASC
)
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Categories](
[CategoryID] [bigint] IDENTITY(1,1) NOT NULL
,[CategoryName] [nchar](100) NOT NULL
,CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED (
[CategoryID] ASC
)
) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IDX_Equipment_Category] ON [dbo].[Equipment] (
[CategoryID] ASC
) ON [PRIMARY]
CREATE UNIQUE NONCLUSTERED INDEX [IDX_Categories_CategoryName] ON [dbo].[Categories] (
[CategoryName] ASC
) ON [PRIMARY]
ALTER TABLE [dbo].[Equipment] WITH CHECK ADD CONSTRAINT [FK_Equipment_Categories]
FOREIGN KEY([CategoryID]) REFERENCES [dbo].[Categories] ([CategoryID])
GO
答案 4 :(得分:0)
如果不发布您将拥有的查询和关系,这个问题是无法回答的。
id
引用设备?或者EquipID
? id
值或EquipID
来存储引用(外键)?Category
汇总吗?Category
隐含的层次结构是什么?EquipID
是否有变化?