128

我已经看到了命名存储过程的各种规则。

有些人在 sproc 名称前加上 usp_,有些人使用应用程序名称的缩写,还有一些人使用所有者名称。除非您是认真的,否则不应在 SQL Server 中使用 sp_。

一些以动词(获取、添加、保存、删除)开头的过程名称。其他人则强调实体名称。

在具有数百个存储过程的数据库上,当您认为已经存在一个存储过程时,可能很难滚动并找到合适的存储过程。命名约定可以使定位存储过程更容易。

你使用命名约定吗?请描述它,并解释为什么你更喜欢它而不是其他选择。

回复摘要:

  • 每个人似乎都提倡命名的一致性,因为每个人使用相同的命名约定可能比使用哪个特定的命名约定更重要。
  • 前缀:虽然很多人使用 usp_ 或类似名称(但很少使用 sp_),但许多其他人使用数据库或应用程序名称。一位聪明的 DBA 使用 gen、rpt 和 tsk 来区分一般的 CRUD 存储过程和用于报告或任务的存储过程。
  • 动词+名词似乎比名词+动词更受欢迎。有些人对动词使用 SQL 关键字(Select、Insert、Update、Delete),而另一些人则使用非 SQL 动词(或它们的缩写),例如 Get 和 Add。有些人区分单数名词和复数名词,以表明是否正在检索一条或多条记录。
  • 在适当的情况下,建议在末尾添加一个附加短语。GetCustomerById,GetCustomerBySaleDate。
  • 有些人在名称段之间使用下划线,而有些人则避免使用下划线。app_Get_Customer 与 appGetCustomer——我想这是可读性的问题。
  • 大型存储过程集合可以分离到 Oracle 包或 Management Studio (SQL Server) 解决方案和项目,或 SQL Server 模式中。
  • 应避免使用难以理解的缩写。

为什么我选择我所做的答案:有很多好的回应。谢谢你们!如您所见,很难只选择一个。我选择的那个引起了我的共鸣。我遵循了他描述的相同路径——尝试使用动词+名词,然后找不到适用于客户的所有存储过程。

能够定位现有的 sproc,或者确定一个是否存在,是非常重要的。如果有人无意中创建了另一个名称的重复存储过程,则可能会出现严重问题。

由于我通常处理具有数百个存储过程的大型应用程序,因此我更喜欢最容易找到的命名方法。对于较小的应用程序,我可能会提倡动词 + 名词,因为它遵循方法名称的一般编码约定。

他还提倡以应用名称为前缀,而不是用不太有用的 usp_。正如一些人指出的那样,有时数据库包含多个应用程序的存储过程。因此,使用应用程序名称作为前缀有助于隔离存储过程并帮助 DBA 和其他人确定存储过程用于哪个应用程序。

4

17 回答 17

68

对于我的上一个项目,我使用了 usp_[Action][Object][Process],例如,usp_AddProduct 或 usp_GetProductList、usp_GetProductDetail。但是现在数据库有 700 个以上的过程,要找到特定对象上的所有过程变得更加困难。例如,我现在必须为 Product add 搜索 50 个奇数的 Add 过程,为 Get 等搜索 50 个奇数。

因此,在我的新应用程序中,我计划按对象对程序名称进行分组,我也放弃了 usp,因为我觉得它有些多余,除了告诉我它是一个程序,我可以从名称中扣除一些东西程序本身。

新格式如下

[App]_[Object]_[Action][Process]

App_Tags_AddTag
App_Tags_AddTagRelations
App_Product_Add 
App_Product_GetList
App_Product_GetSingle

它有助于将事物分组以便以后更容易找到,尤其是在有大量存储过程的情况下。

关于哪里使用了多个对象,我发现大多数实例都有primary和secondary对象,所以在普通实例中使用primary对象,在process部分中引用secondary,例如App_Product_AddAttribute。

于 2008-10-26T17:50:56.577 回答
37

下面是关于 SQL Server 中 sp_ 前缀问题的一些说明。

以前缀 sp_ 命名的存储过程是存储在 Master 数据库中的系统存储过程。

如果你给你的存储过程这个前缀,SQL Server首先在主数据库中查找它们,然后是上下文数据库,因此不必要地浪费资源。而且,如果用户创建的存储过程与系统存储过程同名,用户创建的存储过程将不会被执行。

sp_ 前缀表示 sproc 可以从所有数据库访问,但它应该在当前数据库的上下文中执行。

这是一个很好的解释,其中包括性能影响的演示。

这是Ant 在评论中提供的另一个有用的资源。

于 2008-10-26T18:19:05.707 回答
16

Systems Hungarian(如上面的“usp”前缀)让我不寒而栗。

我们在不同的、结构相似的数据库中共享许多存储过程,因此对于特定于数据库的数据库,我们使用数据库名称本身的前缀;共享过程没有前缀。我想使用不同的模式可能是完全摆脱这种有些难看的前缀的替代方法。

前缀后的实际名称与函数命名几乎没有区别:通常是动词,如“Add”、“Set”、“Generate”、“Calculate”、“Delete”等,后跟几个更具体的名词,如“User” ”、“每日收入”等。

回应蚂蚁的评论:

  1. 表和视图之间的区别与设计数据库模式的人有关,而不是与访问或修改其内容的人有关。在需要模式细节的极少数情况下,很容易找到。对于随意的 SELECT 查询,它是无关紧要的。事实上,我认为能够同等对待表和视图是一个很大的优势。
  2. 与函数和存储过程不同,表或视图的名称不太可能以动词开头,或者不是一个或多个名词。
  3. 函数需要调用模式前缀。事实上,函数和存储过程之间的调用语法(无论如何我们都使用)是非常不同的。但即使它不是,与 1. 一样适用:如果我可以将函数和存储过程视为相同,我为什么不应该呢?
于 2008-10-26T17:29:02.003 回答
11

TableName_WhatItDoes

  • Comment_GetByID

  • 客户列表

  • UserPreference_DeleteByUserID

没有前缀或愚蠢的匈牙利废话。只是与它最密切相关的表的名称,以及它的作用的快速描述。

对上述内容的一个警告:我个人总是在所有自动生成的 CRUD 前加上 zCRUD_ 前缀,这样它就可以排序到列表的末尾,而我不必查看它。

于 2008-10-26T23:48:54.090 回答
10

在 SQL Server 中以 开头的存储过程名称sp_是不好的,因为系统存储过程都以 sp_ 开头。一致的命名(甚至在 hobgoblin-dom 的范围内)很有用,因为它促进了基于数据字典的自动化任务。前缀在 SQL Server 2005 中的用处稍小,因为它支持架构,它可以用于各种类型的命名空间,就像过去的名称前缀一样。例如,在星型模式中,可以有暗淡模式和事实模式,并按此约定引用表。

对于存储过程,前缀可用于从系统存储过程中识别应用存储过程。 up_vs.sp_使得从数据字典中识别非系统存储过程变得相对容易。

于 2008-10-26T17:41:39.963 回答
10

这些年来,我几乎使用了所有不同的系统。我终于开发了这个,我今天继续使用它:

字首 :

  • gen - 一般:CRUD,主要是
  • rpt - 报告:不言自明
  • tsk - 任务:通常具有程序逻辑,通过预定作业运行

动作说明符:

Ins - INSERT
Sel - SELECT
Upd - UPDATE
Del - DELETE

(在过程做很多事情的情况下,总体目标用于选择操作说明符。例如,客户 INSERT 可能需要大量准备工作,但总体目标是 INSERT,因此选择“Ins”。

目的:

对于 gen (CRUD),这是受影响的表或视图名称。对于 rpt(报告),这是报告的简短描述。对于 tsk(任务),这是任务的简短描述。

可选澄清剂:

这些是用于增强对程序的理解的可选信息位。示例包括“By”、“For”等。

格式:

[前缀][动作说明符][实体][可选说明符]

过程名称示例:

genInsOrderHeader

genSelCustomerByCustomerID
genSelCustomersBySaleDate

genUpdCommentText

genDelOrderDetailLine

rptSelCustomersByState
rptSelPaymentsByYear

tskQueueAccountsForCollection
于 2008-10-26T18:49:58.313 回答
5

对于小型数据库,我使用 uspTableNameOperationName,例如 uspCustomerCreate、uspCustomerDelete 等。这有助于按“主”实体进行分组。

对于较大的数据库,添加模式或子系统名称,例如 Receiving、Purchasing 等以将它们组合在一起(因为 sql server 喜欢按字母顺序显示它们)

为了清楚起见,我尽量避免名称中的缩写(并且项目中的新人不必想知道“UNAICFE”代表什么,因为存储空间被命名为uspUsingNoAbbreviationsIncreasesClarityForEveryone)

于 2008-10-26T17:16:42.370 回答
4

我总是将存储过程封装在中(我正在使用 Oracle,在工作中)。这将减少单独对象的数量并有助于代码重用。

命名约定是个人喜好问题,您应该在项目开始时与所有其他开发人员达成一致。

于 2008-10-26T17:09:05.147 回答
4

我目前使用如下格式

符号:

[前缀] [应用] [模块]_[名称]

例子:

P_CMS_USER_UserInfoGet

我喜欢这个符号有几个原因:

  • 以非常简单的前缀开头允许编写代码以仅执行以前缀开头的对象(例如,以减少 SQL 注入)
  • 在我们更大的环境中,多个团队正在开发运行相同数据库架构的不同应用程序。应用程序符号指定哪个组拥有 SP。
  • Module 和 Name 部分只是完成了层次结构。所有名称都应该能够与层次结构中的 Group/App、Module、Function 匹配。
于 2008-10-26T21:02:24.317 回答
2

我总是使用:

usp[表名称][操作][额外细节]

给定一个名为“tblUser”的表,这给了我:

  • usp用户创建
  • usp用户选择
  • uspUserSelectByNetworkID

这些过程按表名和功能按字母顺序排序,因此很容易看出我可以对任何给定的表做什么。使用前缀“usp”让我知道我在(例如)编写一个与其他过程、多个表、函数、视图和服务器交互的 1000 行过程时我在调用什么。

在 SQL Server IDE 中的编辑器与 Visual Studio 一样好之前,我会保留前缀。

于 2008-10-26T17:54:22.233 回答
2

应用程序前缀_操作前缀_所涉及的数据库对象的描述(减去下划线之间的空格-必须放入空格才能显示)

我们使用的操作前缀 -

  • “<em>get” – 返回一个记录集
  • “<em>ins”——插入数据
  • “<em>upd” – 更新数据
  • “<em>del” – 删除数据

例如

wmt_ins_customer_details

“劳动力管理工具,将详细信息插入客户表”

好处

与同一应用程序相关的所有存储过程都按名称分组在一起。在组内,执行相同类型的操作(例如插入、更新等)的存储过程被分组在一起。

这个系统对我们很有效,大约有。一个数据库中的 1000 个存储过程让我难以想象。

到目前为止,还没有遇到这种方法的任何缺点。

于 2008-10-26T18:45:35.420 回答
2

GetXXX - 根据@ID 获取 XXX

GetAllXXX - 获取所有 XXX

PutXXX - 如果传递的@ID 为 -1,则插入 XXX;其他更新

DelXXX - 根据@ID 删除 XXX

于 2008-10-26T23:11:52.543 回答
1

我认为 usp_ 命名约定没有任何好处。

过去,我使用 Get/Update/Insert/Delete 前缀进行 CRUD 操作,但现在由于我使用 Linq to SQL 或 EF 来完成我的大部分 CRUD 工作,这些都完全消失了。由于我的新应用程序中存储的过程非常少,因此命名约定不再像以前那样重要;-)

于 2008-10-26T17:17:49.763 回答
1

对于我正在开发的当前应用程序,我们有一个标识应用程序名称的前缀(四个小写字母)。这样做的原因是我们的应用程序必须能够与同一数据库中的遗留应用程序共存,因此前缀是必须的。

如果我们没有遗留约束,我很确定我们不会使用前缀。

在前缀之后,我们通常以描述过程做什么的动词开头 SP 名称,然后是我们操作的实体的名称。允许实体名称的复数形式 - 我们试图强调可读性,以便仅从名称中就可以明显看出该过程的作用。

我们团队中典型的存储过程名称是:

shopGetCategories
shopUpdateItem
于 2008-10-26T17:20:05.780 回答
1

只要您合乎逻辑且始终如一,我认为您的前缀是什么并不重要。我个人使用

spu_[动作描述][过程描述]

其中动作描述是一小部分典型动作之一,例如获取、设置、归档、插入、删除等。过程描述简短但具有描述性,例如

spu_archiveCollectionData 

或者

spu_setAwardStatus

我以类似方式命名我的函数,但前缀为 udf_

我看到人们尝试使用伪匈牙利符号来命名程序,在我看来,这隐藏的比它揭示的要多。只要当我按字母顺序列出我的程序时,我可以看到它们按功能分组,那么对我来说,这似乎是秩序和不必要的严谨之间的最佳点

于 2008-10-26T17:38:55.197 回答
1

避免在 SQl 服务器中使用 sp_*,因为所有系统存储的过程都以 sp_ 开头,因此系统更难找到与名称对应的对象。

所以如果你从 sp_ 以外的东西开始,事情就会变得更容易。

所以我们使用一个通用的 Proc_ 命名开始。如果提供一个大模式文件,这将更容易识别过程。

除此之外,我们分配了一个前缀来标识该功能。像

Proc_Poll_Interface, Proc_Inv_Interface等等

这使我们能够找到执行 POLL 的工作与执行 Inventory 等工作的所有存储过程。

无论如何,前缀系统取决于您的问题域。但是,即使只是为了让人们在资源管理器下拉列表中快速定位存储过程进行编辑,也应该存在类似的说法和所做的事情。

其他例如功能。

Proc_Order_Place
Proc_order_Delete
Proc_Order_Retrieve
Proc_Order_History

我们遵循基于函数的命名,因为 Procs 类似于代码/函数,而不是像表这样的静态对象。Procs 可能与多个表一起工作并没有帮助。

如果 proc 执行的功能比单个名称所能处理的要多,则意味着您的 proc 正在做的事情远远超出了必要的范围,是时候再次拆分它们了。

希望有帮助。

于 2008-10-26T17:58:33.673 回答
1

我迟到了,但我想在这里输入我的回复:

在我最近的两个项目中,有不同的趋势,比如我们使用的一个:

获取数据:s<tablename>_G
删除数据:s<tablename>_D
插入数据:s<tablename>_I
更新数据:s<tablename>_U

前端也遵循此命名约定,前缀为dt

例子:

exec sMedicationInfo_G
exec sMedicationInfo_D
exec sMedicationInfo_I
exec sMedicationInfo_U

借助我们应用程序中的上述命名约定,我们有了一个好记且易于记忆的名称。

在第二个项目中,我们使用了相同的命名约定,但略有不同:

获取数据:sp_<tablename>G
删除数据:sp_<tablename>D
插入数据:sp_<tablename>I
更新数据:sp_<tablename>U

例子:

exec sp_MedicationInfoG
exec sp_MedicationInfoD
exec sp_MedicationInfoI
exec sp_MedicationInfoU
于 2009-06-13T22:32:58.493 回答