对于TVP中使用的表类型是否有最佳实践或策略?例如,考虑到以下情况:
CREATE TABLE dbo.Colors (
Id int identity PRIMARY KEY,
Name nvarchar(100),
);
CREATE TABLE dbo.Shapes (
Id int identity PRIMARY KEY,
Name nvarchar(100),
);
CREATE TABLE dbo.Materials (
Id int identity PRIMARY KEY,
Name nvarchar(100),
);
CREATE TABLE dbo.Items (
Id int identity PRIMARY KEY,
Name nvarchar(100),
ColorId int FOREIGN KEY REFERENCES dbo.Colors (ID),
ShapeId int FOREIGN KEY REFERENCES dbo.Shapes (ID),
MaterialId int FOREIGN KEY REFERENCES dbo.Materials (ID),
);如果您实现了一个存储过程,用于搜索支持通过TVP选择多颜色、多个形状和多个材料的项(UI中的复选框列表),您会创建三种不同的表类型,每个TVP一种,还是会创建一种用于在所有三种情况下使用它的类型?
换言之,这是:
CREATE TYPE dbo.ColorIds AS TABLE (Id int);
CREATE TYPE dbo.ShapeIds AS TABLE (Id int);
CREATE TYPE dbo.MaterialIds AS TABLE (Id int);
GO
CREATE PROCEDURE dbo.SearchItems
@ColorIds ColorIds READONLY,
@ShapeIds ShapeIds READONLY,
@MaterialIds MaterialIds READONLY
AS
BEGIN
PRINT 'Do something here'
END
GO相对于此:
CREATE TYPE dbo.Ids AS TABLE (Id int);
GO
CREATE PROCEDURE dbo.SearchItems
@ColorIds Ids READONLY,
@ShapeIds Ids READONLY,
@MaterialIds Ids READONLY
AS
BEGIN
PRINT 'Do something here'
END
GO示例是有意设计的;真正的用例由更多的表组成,这些表虽然有不同的列,但都有一个ID int主键。正因为如此,我个人更倾向于做后者。它的开销要小得多,但我很想知道在这样做时是否有什么缺点。当然,这只适用于TVP和TVP(我永远不会将不同的实体混合在一个真正的表中,或者任何其他更永久的结构中)。
在此期间,您对命名表类型和TVP的命名约定是什么?
发布于 2019-03-17 16:52:39
我个人在我的系统中使用后者,更通用的版本。我有两个表可以从我的头顶上想到:UniqueIntegerTable和UniqueStringTable --正如您可以想象的那样,它们的定义如下:
CREATE TYPE Utils.UniqueIntegerTable AS TABLE (
[Value] INT NOT NULL PRIMARY KEY
);
CREATE TYPE Utils.UniqueStringTable AS TABLE (
[Value] NVARCHAR(50) NOT NULL PRIMARY KEY
);我更喜欢通用的TVP,这样我就不会用基本上相同的多个类型来阻塞我的模式。性能与在第一个示例中定义的显式类型完全相同,而且它的好处是它为我创建了更少的代码以供维护。
我知道以前我曾听说过使用绑定到表的显式类型的一个论点,那就是更容易理解它们的用法。我个人不同意这一点。没有什么可以阻止我使用错误的类型定义存储过程(但是我的需要有正确的形状)。相反,我可以给变量一个很好的名称来推断使用情况和表的内容:
CREATE PROCEDURE dbo.UpdateEmployees (
@employeeIds Utils.UniqueIntegerTable READONLY
)
BEGIN
SET NOCOUNT ON;
-- Use table as needed.
END
GO在命名约定方面,我不知道任何官方标准,但我使用的标准是将Table附加到类型名称的末尾。我知道,这和用tbl作为前缀并没有什么不同,但在这种情况下,我对此很满意。就像所有的命名惯例一样,选择一个你觉得很容易使用的方法--但是一旦你做到了,就坚持它。只有在一致的情况下,命名约定才会有用。
https://dba.stackexchange.com/questions/232372
复制相似问题