And*_*eas 141 database database-design coding-style naming-conventions relational-database
我正在开始一个新项目,并希望从一开始就获得我的表名和列名.例如,我总是在表名中使用复数,但最近学到的单数是正确的.
那么,如果我得到一个表"用户"然后我得到的产品只有用户会有,那么这个表应该命名为"user_product"还是只是"product"?这是一对多的关系.
进一步说,如果我(由于某种原因)每个产品的几个产品描述,它会是"user_product_description"或"product_description"还是只是"描述"?当然有正确的外键设置..命名它只描述会有问题,因为我也可以有用户说明或帐户描述或其他..
如果我想要一个只有两列的纯关系表(多对多),那会是什么样子呢?"user_stuff"或者类似"rel_user_stuff"的内容?如果是第一个,可以区分它,例如"user_product"?
任何帮助都非常感谢,如果有你们推荐的某种命名约定标准,请随时链接.
谢谢
Per*_*DBA 352
表•名称
最近学到的单数是正确的
是.小心异教徒.表名中的多个表示某人没有阅读任何标准材料并且不了解数据库理论.
关于标准的一些美妙的事情是:
标准表名称是指表中的每一行,它用于所有措辞,而不是表的总内容(我们知道该Customer表包含所有客户).
关系,动词短语
在已建模的真正关系数据库中(与在SQL数据库容器中实现的记录文件系统相对):
当然,这种关系在SQL中实现为子表中的外键约束(更多,稍后).这是动词短语(在模型中),它代表的谓词(从模型中读取),以及FK 约束名称:
Initiates
Each Customer Initiates 0-to-n SalesOrders
Customer_Initiates_SalesOrder_fk
Run Code Online (Sandbox Code Playgroud)
表•语言
但是,在描述表格时,特别是在谓词或其他文档等技术语言中,使用单数和复数,因为它们在英语中很自然.请记住,表是以单行(关系)命名的,而语言是指每个派生行(派生关系):
Each Customer initiates zero-to-many SalesOrders
Run Code Online (Sandbox Code Playgroud)
不
Customers have zero-to-many SalesOrders
Run Code Online (Sandbox Code Playgroud)
那么,如果我得到一个表"用户",然后我得到的产品只有用户会有,那么这个表应该命名为"用户产品"还是"产品"?这是一对多的关系.
(这不是一个命名约定问题;这是一个db设计问题.)如果Record IDs是1 :: n 并不重要.重要的是,是否CONSTRAINT FOREIGN KEY是一个单独的实体,是否是一个独立的表,即.它可以独立存在.因此user::product,不是product.
并且如果product仅存在于a的上下文中user_product,即.它是一个相关表,因此product.
而且,如果我(由于某种原因)对每种产品有几个产品描述,它会是"用户 - 产品描述"或"产品描述"还是仅仅是"描述"?当然使用正确的外键设置..仅命名它描述会有问题,因为我也可能有用户描述或帐户描述或其他.
那就对了.无论是user异或user_product将是正确的,基于以上.它不是要将它与其他区别开来user_product_description,而是让名称感知它所属的位置,前缀是父表.
如果我想要一个只有两列的纯关系表(多对多),那会是什么样子呢?"用户的东西"或者像"rel-user-stuff"之类的东西?如果是第一个,那么可以区分它,例如"用户产品"?
希望关系数据库中的所有表都是纯关系规范化表.没有必要在名称中标识(否则所有表格都是product_description).
如果它包含只在两个亲本的PK(它解决了逻辑 Ñ:: N的关系并不作为一个实体在逻辑层的存在,为物理表),这是一个关联表.是的,通常名称是两个父表名的组合.
如果你最终得到两个xxxx_descriptions表,那么这是一个非常响亮的信号,你没有规范化数据.因此,请返回几步并执行此操作,并准确一致地命名表格.这些名称将自行解决.
任何帮助都非常感谢,如果有你们推荐的某种命名约定标准,请随时链接.
What you are doing is very important, and it will affect the ease of use and understanding at every level. So, it is good to get as much understanding as possible at the outset. The relevance of most of this will not be clear, until you start coding in SQL.
Case is the first item to address. All caps is unacceptable. Mixed case is normal, especially if the tables are directly accessible by the users. Refer my data models. Note that when the seeker is using some demented NonSQL, that has only lowercase, I give that, in which case I include underscores (as per your examples).
Maintain a data focus, not an application or usage focus. It is, after all 2011, we have had Open Architecture since 1984, and databases are supposed to be independent of the apps that use them.
That way, as they grow, and more than the one app uses them, the naming will remain meaningful, and need no correction. (Databases that are completely embedded in a single app are not databases.) Name the data elements as data, only.
Be very considerate, and name tables and columns very accurately. Do not use rel_something if it is a user_product datatype, use UpdatedDate. Do not useDATETIME if it contains a dosage.
It is important to be consistent across the database. Do not use UpdatedDtm in one place to indicate number of Products and _description or NumProductin another place to indicate number of Items. Use ItemNo for numbers-of, and ItemNum or NumSomething for identifiers, consistently.
Do not prefix the column name with a table name or short code, such as SomethingNo. SQL already provides for the tablename as a qualifier:
table_name.column_name -- notice the dot
Run Code Online (Sandbox Code Playgroud)Exceptions:
The first exception is for PKs, they need special handling because you code them in joins, all the time, and you want keys to stand out from data columns. Always use SomethingId, never user_first_name.
user_id is the column that identifies an user, not the id of the user_id table.
id table will have an user as a component of its PK user_product.user_id on many tables, it is easy get mixed up in SQL coding. Second, anyone other that the initial coder has no idea what he was trying to do. Both of which are easy to prevent, if the key columns are treated as above.The second exception is where there is more than one FK referencing the same parent table table, carried in the child. As per the Relational Model, use Role Names to differentiate the meaning or usage, eg. (user_id, product_no) and id for two AssemblyCode. And in that case, do not use the undifferentiated ComponentCode for one of them. Be precise.
Prefix
Where you have more than say 100 tables, prefix the table names with a Subject Area:
PartCodes for Reference tables
PartCode for the Order Entry cluster, etc.
Only at the physical level, not the logical (it clutters the model).
Suffix
Never use suffixes on tables, and always use suffixes on everything else. That means in the logical, normal use of the database, there are no underscores; but on the administrative side, underscores are used as a separator:
REF_ View (with the main OE_ in front, of course)
_V Foreign Key (the constraint name, not the column name)
TableName Cache
_fk Segment
_cac Transaction (stored proc or function)
_seg Function (non-transactional), etc.
The format is the table or FK name, an underscore, and action name, an underscore, and finally the suffix.
This is really important because when the server gives you an error message:
_____tr
you know exactly what object was violated, and what it was trying to do:
_____fn
Foreign Keys (the constraint, not the column). The best naming for a FK is to use the Verb Phrase (minus the "each" and the cardinality).
blah blah blah error on object_name
blah blah blah error on Customer_Add_tr
Customer_Initiates_SalesOrder_fk
Use the Part_Comprises_Component_fk sequence, not Part_IsConsumedIn_Assembly_fk is because (a) it shows up in the correct sort order when you are looking for them and (b) we always know the child involved, what we are guessing at is, which parent. The error message is then delightful:
____Parent_Child_fk.
That works well for people who bother to model their data, where the Verb Phrases have been identified. For the rest, the record filing systems, etc, use Child_Parent_fk.
Indices are special, so they have a naming convention of their very own, made up of, in order, each character position from 1 to 3:
Foreign key violation on Vendor_Offers_PartVendor_fk Unique, or Parent_Child_fk for non-unique
U Clustered, or _ for non-clustered
C separator
For the remainder:
If the key is one column or a very few columns:
_____
If the key is more than a few columns:
_____ Primary Key (as per model)
____ColumnNames Alternate Key (IDEF1X term)
Note that the table name is not required in the index name, because it always shows up as PK
So, when AK[*n*] or table_name.index_name. appears in an error message, it tells you something meaningful. When you look at the indices on a table, you can differentiate them easily.
Find someone qualified and professional and follow them. Look at their designs and study the naming conventions they use. Ask them specific questions about anything you do not understand. Conversely, run like hell from anyone who demonstrates little regard for naming conventions or standards. Here's a few to get you started:
Order Entry & Inventory with Standard-compliant Addresses
Simple inter-office Bulletin system for PHP/MyNonSQL
Sensor Monitoring with full Temporal capability
That cannot be reasonably answered in the comment space.
Larry Lustig:
... even the most trivial example shows ...
If a Customer has zero-to-many Products and a Product has one-to-many Components and a Component has one-to-many Suppliers and a Supplier sells zero-to-many Components and a SalesRep has one-to-many Customers what are the "natural" names the tables holding Customers, Products, Components, and Suppliers?
There are two major problems in your comment:
You declare your example to be "the most trivial", however, it is anything but. With that sort of contradiction, I am uncertain if you are serious, if technically capable.
That "trivial" speculation has several gross Normalisation (DB Design) errors.
Until you correct those, they are unnatural and abnormal, and they do not make any sense. You might as well name them abnormal_1, abnormal_2, etc.
You have "suppliers" who do not supply anything; circular references (illegal, and unnecessary); customers buying products without any commercial instrument (such as Invoice or SalesOrder) as a basis for the purchase (or do customers "own" products?); unresolved many-to-many relationships; etc.
Once that is Normalised, and the required tables are identified, their names will become obvious. Naturally.
In any case, I will try to service your query. Which means I will have to add some sense to it, not knowing what you meant, so please bear with me. The gross errors are too many to list, and given the spare specification, I am not confident I have corrected them all.
I will assume that if the product is made up of components, then the product is an assembly, and the components are used in more than one assembly.
Further, since "Supplier sells zero-to-many Components", that they do not sell products or assemblies, they sell only components.
Speculation vs Normalised Model
In case you are not aware, the difference between square corners (Independent) and round corners (Dependent) is significant, please refer to the IDEF1X Notation link. Likewise the solid lines (Identifying) vs dashed lines (Non-identifying).
... what are the "natural" names the tables holding Customers, Products, Components, and Suppliers?
Now that I have resolved the tables, I don't understand your problem. Perhaps you can post a specific question.
VoteCoffee:
How are you handling the scenario Ronnis posted in his example where multiple relationships exist between 2 tables (user_likes_product, user_bought_product)? I may misunderstand, but this seems to result in duplicate table names using the convention you detailed.
Assuming there are no Normalisation errors, Customer.UC_CustomerId is a predicate, not a table. Do not confuse them. Refer to my Answer, where it relates to subjects, verbs, and predicates, and my response to Larry immediately above.
Each table contains a set of Facts (each row is a Fact), not predicates. Predicates (or propositions), are not Facts, they may or may not be true.
A query is a test of a Predicate (or a number of Predicates, chained together) that results in true (the Fact exists) or false (the Fact does not exist).
Thus, tables should be named, as detailed in my Answer (naming conventions), for the row, the Fact, and the Predicates should be documented (by all means, it is part of the database documentation), but as a separate list of Predicates.
This is not a suggestion that they are not important. They are very important, but I won't write that up here.
Quickly, then. Since the Relational Model is founded on FOL, the entire database can be said to be a set of declarations, a set of Predicates. But (a) there are many types of Predicates, and (b) a table does not represent a Predicate (it is the physical implementation of many Predicates, and of different types of Predicates).
Therefore, naming the table for "the" Predicate that it "represents" is an absurd concept.
The "theoreticians" are aware of only a few Predicates, they do not understand that since the RM was founded on the FOL, the entire database is a set of Predicates, and of different types.
And of course, they choose absurd ones from the few that they do know: EXISTING_PERSON; PERSON_IS_CALLED. If it were not so sad, it would be hilarious.
Note also that the Standard or atomic table name (naming the row) works brilliantly for all the verbiage (including all Predicates attached to the table). Conversely, the idiotic "table represents predicate" name cannot. Which is fine for the "theoreticians", who understand very little about Predicates, but retarded otherwise.
The Predicates that are relevant to the data model, are expressed in the model, they are of two kinds.
The first set is in diagrammatic, not text, form: the notation. These include various Existential; Constraint-oriented; and Descriptor (attributes) Predicates.
Of course, that means only those who can 'read' a Standard data model can read those Predicates. Which is why the "theoreticians", who are severely crippled by their text-only mindset, cannot read data models, why they stick to their pre-1984 text-only mindset.
The second set is those Predicates that form relationships between Facts. This is the relationship line. The Verb Phrase (detailed above) identifies the Predicate, the proposition, that has been implemented (which can be tested via query). One cannot get more explicit than that.
Therefore, to one who is fluent in Standard data models, all the Predicates that are relevant, are documented in the model. They do not need a separate list of Predicates (but the users do!).
Here is a Data Model, where I have listed the Predicates. I have chosen that example because it shows the Existential, etc, Predicates, as well as the Relationship ones, the only Predicates not listed are the Descriptors. Here, due to the seeker's learning level, I am treating him as an user.
Therefore, the event of more than one child table between two parent tables is not a problem, just name them as the Existential Fact re their content, and normalise the names.
The rules I gave for Verb Phrases for relation
Ron*_*nis 17
奇异与复数:选择一个并坚持下去.
列不应以前缀/后缀/固定为前缀或以任何方式固定,并引用它是一个列.表格也是如此.不要将表命名为EMPLOYEE_T或TBL_EMPLOYEES,因为第二个用视图替换,事情变得非常混乱.
不要在名称中嵌入类型信息,例如varchar的"vc_firstname"或"flavour_enum".也不要在列名中嵌入约束,例如"department_fk"或"employee_pk".
其实,关于*修正我能想到的,唯一的好处是,你可以使用保留字一样where_t,tbl_order,user_vw.当然,在这些例子中,使用复数将解决问题:)
不要将所有键命名为"ID".引用相同内容的键在所有表中应该具有相同的名称.用户标识列可以在用户表中称为USER_ID,并且所有表都可以引用该用户.重命名的唯一时间是不同用户正在播放不同的角色,例如Message(sender_user_id,receiver_user_id).这在处理更大的查询时非常有用.
关于CaSe:
thisiswhatithinkofalllowercapscolumnnames.
ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME.
CamelCaseIsMarginallyBetterButItStillTakesTimeToParse.
i_recommend_sticking_with_lower_case_and_underscore
Run Code Online (Sandbox Code Playgroud)
通常,最好将"映射表"命名为与其描述的关系相匹配,而不是引用表的名称.用户可以有任意数量的关系,产品:user_likes_product,user_bought_product,user_wants_to_buy_product.
Jon*_*ler 16
关于单数与复数没有"正确" - 这主要是品味问题.
这部分取决于你的关注点.如果您将表视为一个单元,它将保留"复数"(因为它包含许多行 - 因此复数名称是合适的).如果您将表名视为标识表中的行,则您更喜欢"单数".这意味着您的SQL将被视为从表中的一行开始工作.没关系,虽然这通常是过于简单化了; SQL适用于集合(或多或少).但是,我们可以单数用于解答这个问题.
由于您可能需要一个表'用户',另一个'产品',以及第三个将用户连接到产品,因此您需要一个表'user_product'.
由于描述适用于产品,因此您将使用"product_description".除非每个用户为自己命名每个产品......
'user_product'表是(或可能是)具有产品ID和用户ID的表的示例,而不是其他.您以相同的一般方式命名两个属性表:'user_stuff'.像'rel_'这样的装饰前缀并没有真正帮助.例如,您会看到有些人在每个表名前面使用't_'.这不是很多帮助.