首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通用TVP权衡?

通用TVP权衡?
EN

Database Administration用户
提问于 2019-03-17 16:12:30
回答 1查看 298关注 0票数 6

对于TVP中使用的表类型是否有最佳实践或策略?例如,考虑到以下情况:

代码语言:javascript
复制
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一种,还是会创建一种用于在所有三种情况下使用它的类型?

换言之,这是:

代码语言:javascript
复制
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

相对于此:

代码语言:javascript
复制
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的命名约定是什么?

EN

回答 1

Database Administration用户

回答已采纳

发布于 2019-03-17 16:52:39

我个人在我的系统中使用后者,更通用的版本。我有两个表可以从我的头顶上想到:UniqueIntegerTableUniqueStringTable --正如您可以想象的那样,它们的定义如下:

代码语言:javascript
复制
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,这样我就不会用基本上相同的多个类型来阻塞我的模式。性能与在第一个示例中定义的显式类型完全相同,而且它的好处是它为我创建了更少的代码以供维护。

我知道以前我曾听说过使用绑定到表的显式类型的一个论点,那就是更容易理解它们的用法。我个人不同意这一点。没有什么可以阻止我使用错误的类型定义存储过程(但是我的需要有正确的形状)。相反,我可以给变量一个很好的名称来推断使用情况和表的内容:

代码语言:javascript
复制
CREATE PROCEDURE dbo.UpdateEmployees (
    @employeeIds Utils.UniqueIntegerTable READONLY
)
BEGIN
SET NOCOUNT ON;

-- Use table as needed.

END
GO

在命名约定方面,我不知道任何官方标准,但我使用的标准是将Table附加到类型名称的末尾。我知道,这和用tbl作为前缀并没有什么不同,但在这种情况下,我对此很满意。就像所有的命名惯例一样,选择一个你觉得很容易使用的方法--但是一旦你做到了,就坚持它。只有在一致的情况下,命名约定才会有用。

票数 7
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/232372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档