SQL Server索引 - 验证命名约定

时间:2017-10-27 09:28:44

标签: sql-server naming-conventions

我正在寻找一个T-SQL脚本,可以验证我的索引是否正确命名。

PK_ for primary keys
UK_ for unique keys
IX_ for non clustered non unique indexes
UX_ for unique indexes

此外,索引的命名(棘手的部分):

IX_Column1_Column2 - instead of IX_CrazyIndexWhichFixesPerformance

有人使用这种类型的脚本吗?

2 个答案:

答案 0 :(得分:1)

使用对象目录视图(sys。*)很容易实现。

这取决于你想要如何处理 - 你可以写一个完整的程序来检查所有这些事情。我没有完全符合上述条件的代码,但这应该让你走上正轨。

对于主键检查,您可以找到不符合命名方案的主键:

SELECT distinct 
i.name AS index_name,
i.object_id
from
sys.indexes i
where
i.is_primary_key = 1
and i.name not like 'PK_%'

这将是使用sys.objects表来过滤特定键约束的问题。

对于列,请加入sys.index_columnssys.columns

SELECT distinct 
c.name AS column_name,
i.name AS index_name,
i.object_id
from
sys.indexes i
inner join sys.index_columns ic  ON i.object_id = ic.object_id AND i.index_id = ic.index_id
inner join sys.columns c ON ic.object_id = c.object_id AND c.column_id = ic.column_id

由于您希望将列名称连接到一个字段,因此需要查看FOR XML PATH('')

此信息加上仔细操作您需要的命名约定应允许您执行这些检查。

答案 1 :(得分:0)

我最终得到了这个 - 它可能不是很漂亮,但现在已经完成了工作: - )

WITH indexesCTE
AS
(
    SELECT 
        t.name AS TableName
        , i.name AS IndexName 
        , i.index_id AS IndexId
        , ic.index_column_id AS ColumnId
        , t.object_id AS TableId
        , REPLACE(c.name, '_', '') AS ColumnName
        , i.object_id AS IndexObjectId
    FROM sys.indexes i 
    INNER JOIN sys.index_columns ic ON  i.object_id = ic.object_id and i.index_id = ic.index_id 
    INNER JOIN sys.columns c ON ic.object_id = c.object_id and ic.column_id = c.column_id 
    INNER JOIN sys.tables t ON i.object_id = t.object_id 
    WHERE 
         i.is_primary_key = 0 
         AND i.is_unique = 0 
         AND i.is_unique_constraint = 0 
         AND t.is_ms_shipped = 0 
)
, indexNameProposal
AS
(
SELECT  i.TableName
        , i.IndexName AS CurrentIndexName
        , 'IX' + STUFF((SELECT '_' + i2.ColumnName FROM indexesCTE i2 WHERE i2.IndexId = i.IndexId AND i.TableId = i2.TableId FOR XML PATH('')),1,0,'') AS IndexNameProposal
        FROM indexesCTE i
        GROUP BY i.TableName, i.IndexName, i.TableId, i.IndexId
)
SELECT 
    *
    FROM indexNameProposal i
    WHERE i.CurrentIndexName <> i.IndexNameProposal