存储过程的命名约定是什么?
我已经看到了命名存储过程的各种规则。
一些人在usp_前面加上了sproc的名字,其他的名字是应用名称的缩写,还有一些是所有者的名字。 除非你是真正的意思,否则你不应该在SQL Server中使用sp_。
一些用动词(Get,Add,Save,Remove)启动proc名字。 其他则强调实体名称。
在拥有数百个sprocs的数据库中,当您认为已经存在的时候,可能会很难滚动并find合适的sproc。 命名约定可以使查找更简单。
你使用命名约定? 请描述一下,并解释为什么你比其他select更喜欢它。
答复摘要:
- 每个人似乎都提倡命名的一致性,对于每个人来说,使用相同的命名约定可能比使用特定命名约定更为重要。
- 前缀:当很多人使用usp_或类似的东西(但很less使用sp_)时,许多人使用数据库或应用程序名称。 一个聪明的DBA使用gen,rpt和tsk来区分用于报告或任务的一般CRUD sprocs。
- 动词+名词似乎比名词+动词稍微受欢迎。 有些人对动词使用SQL关键字(Select,Insert,Update,Delete),而其他人则使用非SQL动词(或缩写),如Get和Add。 有些区分singluar和复数名词来表示是否正在检索一个或多个logging。
- 最后在适当的地方build议一个额外的短语。 GetCustomerById,GetCustomerBySaleDate。
- 有些人在名字段之间使用下划线,有些人避免使用下划线。 app_ Get_Customer与appGetCustomer – 我想这是一个可读性问题。
- 可以将大量sprocs分离到Oracle包或Management Studio(SQL Server)解决scheme和项目或SQL Server架构中。
- 应该避免不可思议的缩写。
为什么我select我所做的答案:有很多好的答案。 谢谢你们! 正如你所看到的,select一个将是非常困难的。 我select的那个对我产生了共鸣。 我遵循了他描述的相同的path – 尝试使用Verb + Noun,然后无法find所有适用于Customer的sprocs。
能够find现有的sproc,或者确定是否存在,是非常重要的。 如果有人无意中用另一个名字创build了一个重复的sproc,就会出现严重的问题。
由于我通常在数以百计的sprocs非常大的应用程序工作,我有一个最容易find命名方法的首选项。 对于较小的应用程序,我可能会提倡动词+名词,因为它遵循方法名称的通用编码约定。
他还提倡使用应用程序名称而不是非常有用的usp_作为前缀。 正如几个人指出的,有时数据库包含多个应用程序的sprocs。 因此,以应用程序名称作为前缀有助于分离sprocs,并帮助DBA和其他人确定哪个应用程序是用于sproc的。
对于我上一个项目,我使用了usp_ [Action] [Object] [Process],例如usp_AddProduct或usp_GetProductList,usp_GetProductDetail。 然而,现在数据库在700个程序加上,在特定对象上find所有程序变得困难得多。 例如,我现在必须search产品添加50奇怪的添加程序,50奇怪的获取等
因为在我的新应用程序中,我正在计划按对象对过程名称进行分组,除了告诉我它的一个过程外,我还放弃了usp,因为我觉得它有点多余,我可以从程序本身。
新格式如下
[App]_[Object]_[Action][Process] App_Tags_AddTag App_Tags_AddTagRelations App_Product_Add App_Product_GetList App_Product_GetSingle
它有助于将事情分组,以便日后更容易find,特别是如果有大量sprocs。
关于使用多个对象的情况,我发现大多数实例都有主对象和辅助对象,所以主对象在普通实例中使用,辅助对象在进程段中引用,例如App_Product_AddAttribute。
下面是关于SQL Server中sp_前缀问题的一些说明。
使用前缀sp_命名的存储过程是存储在主数据库中的系统sprocs。
如果你把这个前缀放在sproc中,SQL Server首先在主数据库中查找它们,然后在上下文数据库中查找它们,从而不必要地浪费资源。 而且,如果用户创build的sproc与系统sproc具有相同的名称,则用户创build的sproc将不会执行。
sp_前缀表示sproc可以从所有数据库访问,但是应该在当前数据库的上下文中执行。
这里有一个很好的解释,其中包括性能命中的演示。
Ant在评论中提供了另一个有用的源代码。
系统匈牙利 (如上面的“usp”前缀)让我不寒而栗。
我们在不同的,类似结构的数据库之间共享许多存储过程,所以对于数据库特定的数据库,我们使用数据库名称本身的前缀; 共享程序没有前缀。 我想使用不同的模式可能是一个替代scheme来完全摆脱这种有点丑陋的前缀。
前缀之后的实际名称与函数命名几乎没有区别:通常是一个像“添加”,“设置”,“生成”,“计算”,“删除”等动词,接着是几个更具体的名词,如“用户“,”日常收入“等。
回应Ant的评论:
- 表和视图之间的区别与devise数据库模式的人有关,而不是那些访问或修改其内容的人。 在需要特定模式的罕见情况下,很容易find。 对于偶然的SELECT查询,这是无关紧要的。 实际上,我认为能够把桌面和视图看作是一个很大的优势。
- 与函数和存储过程不同的是,表或视图的名称不可能以动词开头,或者只是一个或多个名词。
- 一个函数需要调用模式前缀。 实际上,函数和存储过程之间的调用语法(无论如何)都是非常不同的。 但是,即使不是这样,也是一样的:如果我可以把函数和存储过程同等对待,为什么不呢?
使用sp_
开始存储过程名称在SQL Server中是不好的,因为系统sprocs都是以sp_开头的。 一致的命名(甚至在hobgoblin-dom的范围内)是有用的,因为它促进了基于数据字典的自动化任务。 前缀在SQL Server 2005中稍微有用,因为它支持模式,它可以用于各种types的名称空间,以前缀用于名称的前缀。 例如,在一个星型模式中,可以有模糊的 事实模式,并按照这个约定引用表。
对于存储过程,前缀对于从系统sprocs中识别应用程序sprocs非常有用。 up_
与sp_
使得从数据字典中识别非系统存储过程变得相对容易。
TableName_WhatItDoes
-
Comment_GetByID
-
CUSTOMER_LIST
-
UserPreference_DeleteByUserID
没有前缀或愚蠢的匈牙利废话。 只是最密切相关的表格的名称,以及它所做的工作的快速描述。
一个告诫上述:我个人总是前缀所有我自动生成的CRUD与zCRUD_,以便它sorting到列表的最后,我不必看它。
多年来,我几乎使用了所有不同的系统。 我终于开发了这个我今天继续使用的:
字首 :
- 通用:大多数是CRUD
- rpt – 报告:不言自明
- tsk – 任务:通常是程序逻辑的东西,通过计划任务运行
操作说明符:
Ins - INSERT Sel - SELECT Upd - UPDATE Del - DELETE
(在程序执行很多事情的情况下,总体目标是用来select行动说明符,例如,客户INSERT可能需要大量的准备工作,但总体目标是INSERT,所以select“Ins”。
目的:
对于gen(CRUD),这是受影响的表或视图名称。 对于报告(报告),这是报告的简短描述。 对于tsk(Task),这是任务的简短描述。
可选澄清器:
这些是可选的信息位,用于增强对程序的理解。 例如“By”,“For”等
格式:
[前缀] [操作说明符] [实体] [可选澄清器]
程序名称的例子:
genInsOrderHeader genSelCustomerByCustomerID genSelCustomersBySaleDate genUpdCommentText genDelOrderDetailLine rptSelCustomersByState rptSelPaymentsByYear tskQueueAccountsForCollection
我总是封装存储过程包 (我使用Oracle,在工作中)。 这将减less单独的对象的数量,并帮助代码重用。
命名约定是一个有趣的问题,你应该在项目开始时与所有其他开发者一致。
对于小型数据库,我使用uspTableNameOperationName,例如uspCustomerCreate,uspCustomerDelete等。这有利于通过“main”实体进行分组。
对于较大的数据库,添加模式或子系统名称,例如Receiving,Purchasing等,以便将它们组合在一起(因为SQL Server喜欢按字母顺序显示它们)
为了清楚起见,我尽量避免使用名称中的缩写(项目中的新人不必考虑“UNAICFE”代表什么,因为sproc被命名为uspUsingNoAbbreviationsIncreasesClarityForEveryone)
我目前使用的格式如下所示
符号:
[PREFIX] [APPLICATION] [MODULE] _ [NAME]
例:
P_CMS_USER_UserInfoGet
我喜欢这个符号有几个原因:
- 从非常简单的Prefix开始,允许代码被写入只执行用前缀开始的对象(例如减lessSQL注入)
- 在我们更大的环境中,多个团队正在开发运行相同数据库体系结构的不同应用程序。 应用符号指定哪个组拥有SP。
- “模块”和“名称”部分只是完成了层次结构。 所有的名字应该能够匹配组/应用程序,模块,函数从heirarchy。
我总是使用:
usp [表格名称] [操作] [附加信息]
给定一个名为“tblUser”的表,这给了我:
- uspUserCreate
- uspUserSelect
- uspUserSelectByNetworkID
这些过程按照表名和function按字母顺序排列,所以很容易看到我能对任何给定的表做些什么。 如果我(例如)编写一个与其他程序,多个表,函数,视图和服务器交互的1000行程序,使用前缀“usp”可以让我知道我在调用什么。
在SQL Server IDE中的编辑器和Visual Studio一样好之前,我保留前缀。
应用程序前缀_操作前缀_涉及的数据库对象的描述(减去下划线之间的空格 – 必须放置空格以显示它们) 。
操作前缀我们使用 –
- “ get ” – 返回一个logging集
- “ ins ” – 插入数据
- “ upd ” – 更新数据
- “ del ” – 删除数据
例如
wmt_ ins _ customer _details
“劳动力pipe理工具,将详细信息插入客户表”
优点
所有与同一应用程序相关的存储过程都按名称分组。 在组内,执行相同操作(例如插入,更新等)的存储过程被分组在一起。
这个系统适合我们, 1000个存储过程在我的头顶。
到目前为止,还没有遇到这种方法的任何缺点。
GetXXX – 基于@ID获取XXX
GetAllXXX – 获取所有XXX
PutXXX – 如果传递@ID为-1,则插入XXX; 其他更新
DelXXX – 根据@ID删除XXX
我认为usp_命名约定没有任何好处。
在过去,我使用获取/更新/插入/删除前缀CRUD操作,但现在,因为我使用Linq到SQL或EF来做我的大部分CRUD工作,这些都完全消失了。 由于我的新应用程序中存储了很less的特效,命名约定不再像以前那样重要;-)
对于我正在使用的应用程序,我们有一个标识应用程序名称的前缀(四个小写字母)。 原因是我们的应用程序必须能够与同一个数据库中的遗留应用程序共存,所以前缀是必须的。
如果我们没有传统约束,我相当确定我们不会使用前缀。
在前缀之后,我们通常用一个动词来描述SP名称,该动词描述过程的作用,然后是我们所操作的实体的名称。 实体名称的多元化是允许的 – 我们试图强调可读性,这样就明显地看到了程序的名称。
我们团队中的典型存储过程名称是:
shopGetCategories shopUpdateItem
只要你是合乎逻辑的,一致的,我不认为你的前缀真的很重要。 我个人使用
spu_ [动作说明] [进程说明]
其中动作描述是一个典型的动作,如获取,设置,存档,插入,删除等小范围之一。过程描述是简短的但描述性的,例如
spu_archiveCollectionData
要么
spu_setAwardStatus
我同样命名我的函数,但前缀与udf_
我曾经看到有人试图用伪匈牙利符号来进行程序命名,在我看来,它隐藏的并不多。 只要按照字母顺序列出我的程序,我可以看到它们按function分组,然后对于我来说,这似乎是顺序和不必要的严格性之间的甜蜜点
在SQl服务器中避免sp_ *因为所有系统存储过程都以sp_开始,因此系统更难find与名称对应的对象。
所以,如果你从sp_以外的东西开始,事情会变得更容易。
所以我们使用一个普通的Proc_命名来开始。 如果使用一个大的模式文件,则可以更容易地识别这些过程。
除此之外,我们分配一个标识function的前缀。 喜欢
Proc_Poll_Interface, Proc_Inv_Interface
等
这使我们能够find所有存储过程,而不是做投标工作,比如库存等。
无论如何,前缀系统取决于你的问题领域。 但是al说,做一些类似的事情应该是存在的,即使只是允许人们在explorere下拉菜单中查找存储过程以便编辑。
其他例如function。
Proc_Order_Place Proc_order_Delete Proc_Order_Retrieve Proc_Order_History
我们遵循基于命名的函数,因为Procs类似于代码/函数,而不是像表格这样的静态对象。 它不能帮助Procs可能与多个表一起工作。
如果proc执行的function多于可以用单一名称处理的function,那么意味着你的proc正在做的事情远远超过必要的时间,并且有时间再次分裂它们。
希望有所帮助。
我join了线程,但我想在这里input我的答复:
在我的最后两个项目中有不同的趋势,就像我们用过的一个:
要获取数据: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
借助我们应用程序中的上述命名约定,我们可以很容易地记住名字。
而在第二个项目中,我们使用相同的命名约定和lill的区别:
要获取数据:sp_ <tablename> G
删除数据:sp_ <tablename> D
要插入数据:sp_ <tablename> I
要更新数据:sp_ <tablename> U
例:
exec sp_MedicationInfoG exec sp_MedicationInfoD exec sp_MedicationInfoI exec sp_MedicationInfoU