Yes. Plural in the table names are a sure sign of someone who has not read any of the standard materials and has no knowledge of database theory.
Some of the wonderful things about Standards are:
they are all integrated with each other
they work together
they were written by minds greater than ours, so we do not have to
debate them.
The standard table name refers to each row in the table, which is used in the all verbiage, not the total content of the table (we know that the Customer table contains all the Customers).
Relationship, Verb Phrase
In genuine Relational Databases that have been modelled (as opposed to pre-1970's Record Filing Systems [characterised by Record IDs which are implemented in an SQL database container for convenience):
the tables are the Subjects of the database, thus they are nouns, again, singular
the relationships between the tables are the Actions that take place between the nouns, thus they are verbs (i.e they are not arbitrarily numbered or named)
that is the Predicate
all that can be read directly from the data model (refer my examples at the end)
(the Predicate for an independent table (the top-most parent in an hierarchy) is that it is independent)
thus the Verb Phrase is carefully chosen, so that it is the most meaningful, and generic terms are avoided (this becomes easier with experience). The Verb Phrase is important during modelling because it assists in resolving the model, ie. clarifying relations, identifying errors, and correcting the table names.
[**Diagram_A**][Diagram_A]
Of course, the relationship is implemented in SQL as a CONSTRAINT FOREIGN KEY in the child table (more, later). Here is the Verb Phrase (in the model), the Predicate that it represents (to be read from the model), and the FK Constraint Name:
Initiates
Each Customer Initiates 0-to-n SalesOrders
Customer_Initiates_SalesOrder_fk
Table • Language
However, when describing the table, particularly in technical language such as the Predicates, or other documentation, use singular and plurals as they naturally in the English language. Keeping in mind the table is named for the single row (relation) and the language refers to each derived row (derived relation):
Each Customer initiates zero-to-many SalesOrders
not
Customers have zero-to-many SalesOrders
So, if I got a table "user" and then I got products that only the user will have, should the table be named "user-product" or just "product"? This is a one to many relationship.
(That is not a naming-convention question; that is a db design question.) It doesn't matter if user::product is 1::n. What matters is whether product is a separate entity and whether it is an Independent Table, ie. it can exist on its own. Therefore product, not user_product.
And if product exists only in the context of an user, ie. it is a Dependent Table, therefore user_product.
[**Diagram_B**][Diagram_B]
And further on, if I would have (for some reason) several product descriptions for each product, would it be "user-product-description" or "product-description" or just "description"? Of course with the right foreign keys set.. Naming it only description would be problematic since I could also have user description or account description or whatever.
That's right. Either user_product_description xor product_description will be correct, based on the above. It is not to differentiate it from other xxxx_descriptions, but it is to give the name a sense of where it belongs, the prefix being the parent table.
What about if I want a pure relational table (many to many) with only two columns, what would this look like? "user-stuff" or maybe something like "rel-user-stuff" ? And if the first one, what would distinguish this from, for example "user-product"?
Hopefully all the tables in the relational database are pure relational, normalised tables. There is no need to identify that in the name (otherwise all the tables will be rel_something).
If it contains only the PKs of the two parents (which resolves the logical n::n relationship that does not exist as an entity at the logical level, into a physical table), that is an Associative Table. Yes, typically the name is a combination of the two parent table names.
Note that is such cases the Verb Phrase applies to, and is read as, from parent to parent, ignoring the child table, because its only purpose in life is to relate the two parents.
[**Diagram_C**][Diagram_C]
If it is not an Associative Table (ie. in addition to the two PKs, it contains data), then name it appropriately, and the Verb Phrases apply to it, not the parent at the end of the relationship.
[**Diagram_D**][Diagram_D]
If you end up with two user_product tables, then that is a very loud signal that you have not normalised the data. So go back a few steps and do that, and name the tables accurately and consistently. The names will then resolve themselves.
Naming Convention
If there is some sort of naming convention standard out there that you guys recommend, feel free to link.
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 kind of 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. 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 UpdatedDate if it is a DATETIME datatype, use UpdatedDtm. Do not use_description if it contains a dosage.
It is important to be consistent across the database. Do not use NumProduct in one place to indicate number of Products and ItemNo or ItemNumin another place to indicate number of Items. Use NumSomething for numbers-of, and SomethingNo or SomethingId for identifiers, consistently.
Do not prefix the column name with a table name or short code, such as user_first_name. SQL already provides for the tablename as a qualifier:
table_name.column_name -- notice the dot
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 user_id, never id.
Note that this is not a table name used as a prefix, but a proper descriptive name for the component of the key: user_id is the column that identifies an user, not the id of the user table.
(Except of course in record filing systems, where the files are accessed by surrogates and there are no relational keys, there they are one and the same thing).
Always use the exact same name for the key column wherever the PK is carried (migrated) as an FK.
Therefore the user_product table will have an user_id as a component of its PK (user_id, product_no).
the relevance of this will become clear when you start coding. First, with an 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. AssemblyCode and ComponentCode for two PartCodes. And in that case, do not use the undifferentiated PartCode for one of them. Be precise.
Prefix
Where you have more than say 100 tables, prefix the table names with a Subject Area:
REF_ for Reference tables OE_ 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:
_V View (with the main TableName in front, of course) _fk Foreign Key (the constraint name, not the column name) _cac Cache _seg Segment _tr Transaction (stored proc or function) _fn 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:
____blah blah blah error on object_name
you know exactly what object was violated, and what it was trying to do:
____blah blah blah error on Customer_Add_tr
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).
Use the Parent_Child_fk sequence, not Child_Parent_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:
____Foreign key violation on Vendor_Offers_PartVendor_fk.
That works well for people who model their data, where the Verb Phrases have been identified. For the rest, the record filing systems, etc, use Parent_Child_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:
U Unique, or _ for non-unique C Clustered, or _ for non-clustered _ separator
For the remainder:
- If the key is one column or a very few columns:
____ColumnNames
Note that the table name is not required in the index name, because it always shows up as table_name.index_name.
So when Customer.UC_CustomerId or Product.U__AK 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 carefully 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:
They contain real examples of all the above. Ask questions re naming questions in this thread.
Of course, the models implement several other Standards, beyond naming conventions; you can either ignore those for now, or feel free to ask specific new questions.
They are several pages each, so you will have to click the links.
Note that PDF files have full navigation, so click on the blue glass buttons, or the objects where expansion is identified:
Readers who are unfamiliar with the Relational Modelling Standard may find the IDEF1X Notation helpful.
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.
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?
Customer
Product
Component
(Or, AssemblyComponent, for those who realise that one fact identifies the other)
Supplier
Now that I have resolved the tables, I don't understand your problem. Perhaps you can post a specific question.
Predicate
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, User likes Product 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). Predicates (or propositions), are not Facts, they may or may not be true.
The Relational Model is based on First Order Predicate Calculus (more commonly known as First Order Logic). A Predicate is a single-clause sentence in simple, precise English, that evaluates to true or false.
Further, each table represents, or is the implementation of, many Predicates, not one.
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 FOPC, the entire database can be said to be a set of FOPC declarations, a set of Predicates. But (a) there are many types of Predicates, and (b) a table does not represent one 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 "table represents predicate" name cannot, which is fine for the "theoreticians", who understand very little about Predicates, but not otherwise.
The Predicates that are relevant to the data model, are expressed in the model, they are of two orders.
Unary Predicate
The first set is diagrammatic, not text: the notation itself. 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.
Binary Predicate
The second set is those that form relationships between Facts. This is the relation 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, who cannot 'read' everything from the data model, 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 relationship names for Associative Tables come into play here. Here is a Predicate vs Table discussion, covering all points mentioned, in summary.
For a good short description re the proper use of Predicates and how to use them (which is quite a different context to that of responding to comments here), visit this answer, and scroll down to the Predicate section.
Charles Burns:
By sequence, I meant the Oracle-style object purely used to store a number and its next according to some rule (e.g. "add 1"). Since Oracle lacks auto-ID tables, my typical use is to generate unique IDs for table PKs. INSERT INTO foo(id, somedata) VALUES (foo_s.nextval, "data"...)
Ok, that is what we call a Key or NextKey table. Name it as such. If you have SubjectAreas, use COM_NextKey to indicate it is common across the database.
Btw, that is a very poor method of generating keys. Not scalable at all, but then with Oracle's performance, it is probably "just fine". Further, it indicates that your database is full of surrogates, not relational in those areas. Which means extremely poor performance and lack of integrity.
不要将所有键命名为“ID”。引用同一事物的键在所有表中应具有相同的名称。用户 id 列在用户表和引用该用户的所有表中可以称为 USER_ID。唯一一次重命名是当不同的用户扮演不同的角色时,例如Message(sender_user_id,receiver_user_id)。这在处理较大的查询时确实很有帮助。
Columns shouldn't be prefixed/suffixed/infixed or in anyway fixed with references to the fact that it is a column. The same goes for tables. Don't name tables EMPLOYEE_T or TBL_EMPLOYEES because the second it is replaced with a view, things get really confusing.
Don't embed type information in names, such as "vc_firstname" for varchar, or "flavour_enum". Also don't embed constraints in column names, such as "department_fk" or "employee_pk".
Actually, the only good thing about *fixes I can think of, is that you can use reserved words like where_t, tbl_order, user_vw. Of course, in those examples, using plural would have solved the issue :)
Don't name all keys "ID". Keys refering to the same thing, should have the same name in all tables. The user id column could be called USER_ID in the user table and all tables referencing the user. The only time it is renamed is when different users are playing different roles, such as Message(sender_user_id, receiver_user_id). This really helps when dealing with larger queries.
In general it is better to name "mapping tables" to match the relation it describes rather than the names of the referenced tables. A user can have any number of relations to products: user_likes_product, user_bought_product, user_wants_to_buy_product.
“user_product”表是(或可能是)具有产品 ID 和用户 ID 的表的示例,仅此而已。您可以使用相同的通用方式命名两个属性表:“user_stuff”。像“rel_”这样的装饰性前缀并没有真正的帮助。例如,您会看到有些人在每个表名称前面使用“t_”。这没什么帮助。
There is no 'correct' about singular vs plural - it is mostly a matter of taste.
It depends in part on your focus. If you think of the table as a unit, it holds 'plurals' (because it holds many rows - so a plural name is appropriate). If you think of the table name as identifying a row in a table, you'll prefer 'singular'. This means your SQL will be thought of as working on one row from the table. That's OK, though it is usually an oversimplification; SQL works on sets (more or less). However, we can go with singular for the answers to this question.
Since you'll probably need a table 'user', another 'product', and the third to connect users to products, then you need a table 'user_product'.
Since the description applies to a product, you would use 'product_description'. Unless each user names each product for themselves...
The 'user_product' table is (or could be) an example of a table with a product ID and a user ID and not much else. You name the two-attribute tables in the same general way: 'user_stuff'. Decorative prefixes like 'rel_' don't really help. You'll see some people using 't_' in front of each table name, for instance. That is not a lot of help.
Plurals aren't bad as long as they are used consistently - but singular is my preference.
I would dispense with underscores unless you want to outline a many-to-many relationship; and use an initial capital because it helps distinguish things in ORMs.
But there are many naming conventions, so if you want to use underscores that's OK as long as its done consistently.
So:
User
UserProduct (it is a users products after all)
If only one user can have any product then
UserProductDescription
But if the product is shared by users:
ProductDescription
If you save your underscores for many-to-many relationships you can do something like:
UserProduct_Stuff
to form a M-to-M between UserProduct and Stuff - not sure from the question the exact nature of the many-to-many required.
There is not more correct to use singular than plural form, where have you heard that? I would rather say that plural form is more common for naming database tables...and in my opinion also more logic. The table most often contain more than one row ;) In a conceptual model though the names of the entities are often in singular.
About your question, if 'Product' and 'ProductDescription' are concepts with an identity (i.e. entities) in your model I would simply call the tables 'Products' and 'ProductDescriptions'. For tables that are used in order to implement a many-to-many relationship I most often use the naming convention "SideA2SideB", for example "Student2Course".
发布评论
评论(5)
表格•名称
是的。表名中的复数显然表明某人没有阅读过任何标准材料并且不了解数据库理论。
标准的一些美妙之处是:
辩论他们。
标准表名是指表中的每一行,用于所有用语,而不是表的全部内容(我们知道
Customer
表包含所有内容)客户)。关系,动词短语
在已建模的真正关系数据库中(与 1970 年之前的记录归档系统相反 [以
记录 ID
为特征,该系统在 SQL 数据库容器中实现方便):[**Diagram_A**][Diagram_A]
当然,这种关系在 SQL 中作为子表中的
CONSTRAINT FOREIGN KEY
来实现(稍后会详细介绍)。这是动词短语(在模型中)、它代表的谓词(从模型中读取)以及 FK 约束名称 >:表格•语言
但是,在描述表格时,尤其是在谓词或其他文档等技术语言中,请使用单数和复数,因为它们在英语中自然使用。请记住,表是根据单行(关系)命名的,并且语言引用每个派生行(派生关系):
不是
(这不是命名约定问题;这是数据库设计问题。)
user::product
是否为 1 并不重要: :n。重要的是product
是否是一个单独的实体以及是否是一个独立表,即。它可以独立存在。因此产品
,而不是user_product
。如果
product
仅存在于user
的上下文中,即。它是一个从属表,因此是user_product
。[**Diagram_B**][Diagram_B]
是的。根据上述内容,
user_product_description
x 或product_description
都是正确的。它不是为了将其与其他xxxx_descriptions
区分开来,而是为了让名称感觉到它所属的位置,前缀是父表。希望关系数据库中的所有表都是纯关系的、规范化的表。无需在名称中标识它(否则所有表都将是
rel_something
)。如果它仅包含两个父级的 PK(这会将逻辑级别上不作为实体存在的逻辑 n::n 关系解析为物理表),即关联表。是的,通常该名称是两个父表名称的组合。
请注意,在这种情况下,动词短语适用于并且被解读为从父表到父表,忽略子表,因为它的唯一目的是将两个父表联系起来。
[**图_C**][图_C]
如果它不是关联表(即除了两个 PK 之外,它还包含数据),则对其进行适当命名,并且动词短语适用于它,而不是关系结束时的父母。
[**图_D**][图_D]
如果您最终得到两个
user_product
表,那么这是一个非常响亮的信号,表明您尚未对数据进行标准化。因此,请返回几步并执行此操作,并准确且一致地命名表。然后名称将自行解析。命名约定
您所做的事情非常重要,它将影响各个级别的易用性和理解。因此,在一开始就获得尽可能多的理解是有好处的。在您开始使用 SQL 进行编码之前,大部分内容的相关性都不会很清楚。
案例是第一个要解决的项目。全部大写是不可接受的。混合大小写是正常的,特别是当用户可以直接访问表时。参考我的数据模型。请注意,当搜索者使用某种只有小写字母的 NonSQL 时,我会给出这一点,在这种情况下,我会包含下划线(根据您的示例)。
保持数据焦点,而不是应用程序或使用焦点。自 1984 年以来,我们一直采用开放架构,数据库应该独立于使用它们的应用程序。
这样,随着它们的成长,并且不止一个应用程序使用它们,命名将保持有意义,并且不需要更正。 (完全嵌入到单个应用程序中的数据库不是数据库。)仅将数据元素命名为数据。
要非常体贴,并且非常准确地命名表和列。如果是
DATETIME
数据类型,请不要使用UpdatedDate
,而应使用UpdatedDtm
。如果_description
包含剂量,请勿使用。整个数据库保持一致非常重要。请勿在一处使用
NumProduct
来指示产品数量,而在另一处使用ItemNo
或ItemNum
来指示商品数量。一致地使用NumSomething
表示数字,使用SomethingNo
或SomethingId
表示标识符。请勿在列名前添加表名或短代码,例如
user_first_name
。 SQL 已经提供表名作为限定符:例外:
第一个例外是 PK,它们需要特殊处理,因为您始终在联接中对它们进行编码,并且您希望键从数据列中脱颖而出。始终使用
user_id
,切勿使用id
。user_id
是标识用户的列,而不是user
表的id
。user_product
表将有一个user_id
作为其 PK(user_id,product_no)
的组成部分。id
,很容易在 SQL 编码中混淆。其次,除了最初的编码员之外的任何人都不知道他想做什么。如果按上述方式处理关键列,这两种情况都很容易预防。第二个例外是有多个 FK 引用同一父表表(在子表中携带)。根据关系模型,使用角色名称来区分含义或用法,例如。两个
PartCodes
的AssemblyCode
和ComponentCode
。在这种情况下,请不要对其中之一使用未区分的PartCode
。准确一点。Diagram_E
前缀
如果您有超过 100 个表,请在表名称前添加主题区域前缀:
REF_
用于参考表OE_
用于订单输入集群等仅在物理层面,而不是逻辑层面(它会使模型变得混乱)。
后缀
切勿在表格上使用后缀,并始终在其他所有内容上使用后缀。这意味着在数据库的逻辑、正常使用中,没有下划线;但在管理方面,下划线用作分隔符:
_V
视图(当然,主TableName
在前面)_fk
外键(约束名称,而不是列名称)_cac
缓存_seg
段_tr
事务(存储过程或函数)_fn
函数(非事务性)等格式是表或FK名称、下划线、动作名称、下划线、最后是后缀。
这非常重要,因为当服务器向您提供错误消息:
____
blah blah blah error on object_name
时,您确切地知道哪个对象被侵犯,以及它试图执行的操作:
____
blah blah Customer_Add_tr 上出现错误
外键(约束,而不是列)。 FK 的最佳命名是使用动词短语(减去“each”和基数)。
Customer_Initiates_SalesOrder_fk
Part_Comprises_Component_fk
Part_IsConsumedIn_Assembly_fk
使用
Parent_Child_fk
序列,而不是Child_Parent_fk
是因为 (a) 当您查找它们时,它会以正确的排序顺序显示,并且 ( b) 我们总是知道所涉及的孩子,我们猜测的是哪个父母。然后错误消息令人愉快:____
Vendor_Offers_PartVendor_fk 上的外键违规
。这对于对数据进行建模的人来说非常有效,其中动词短语已被识别。对于其余的,记录归档系统等,使用Parent_Child_fk。
U
唯一,或_
表示非唯一C
集群,或_
表示非集群_
分隔符其余部分:
- 如果键是一列或极少数列:
____
ColumnNames
____
PK
主键(根据模型)____
AK[*n*]
备用键(IDEF1X 术语)请注意,索引名称中不需要表名称,因为它始终显示为
table_name .index_name.
因此,当
Customer.UC_CustomerId
或Product.U__AK
出现在错误消息中时,它会告诉您一些有意义的信息。当您查看表格上的索引时,您可以轻松地区分它们。订单输入&具有符合标准的地址的库存
简单的办公室间公告 PHP/MySQL 系统
具有完整时间能力的传感器监控
问题的答案
不可能评论区合理回答。
您的评论中有两个主要问题:
您声明您的示例是“最微不足道的”,但是,它只不过是。面对这样的矛盾,我不确定你是否认真,是否有技术能力。
这个“微不足道”的推测有几个严重的标准化(数据库设计)错误。
在你纠正这些错误之前,它们是不自然、不正常的,而且没有任何意义。您不妨将它们命名为异常_1、异常_2 等。
您有不提供任何东西的“供应商”;循环引用(非法且不必要);客户购买产品时没有任何商业票据(例如发票或销售订单)作为购买依据(或者客户“拥有”产品吗?);未解决的多对多关系;等等
一旦标准化,并且确定了所需的表,它们的名称将变得显而易见。当然。
无论如何,我会尽力解答您的疑问。这意味着我必须添加一些意义,不知道你的意思,所以请耐心等待。严重错误太多,无法一一列举,而且考虑到备用规范,我不确信我已经纠正了所有这些错误。
我假设如果产品是由组件组成的,那么该产品就是一个组件,并且组件用于多个组件中。
此外,由于“供应商销售零到多个组件”,因此他们不销售产品或组件,因此他们只销售组件。
投机与标准化模型
如果您不知道,方角(独立)和圆角(从属)之间的差异很大,请参阅 IDEF1X 符号链接。同样,实线(识别)与虚线(非识别)。
(或者,AssemblyComponent,对于那些意识到一个事实可以识别另一个事实的人)
现在我已经解决了这些表,但我不明白您的问题。也许您可以发布具体问题。
谓词
假设没有规范化错误,
User likes Product
是一个谓词,而不是一个表。不要混淆他们。请参阅我的答案,其中涉及主语、动词和谓语,以及我对上面拉里的回应。每个表都包含一组事实(每行都是一个事实)。谓词(或命题)不是事实,它们可能是真的,也可能不是。
关系模型基于一阶谓词演算(通常称为一阶逻辑)。谓词是简单、精确的英语中的单从句句子,其计算结果为 true 或 false。
此外,每个表代表或实现许多谓词,而不是一个。
查询是对谓词(或链接在一起的多个谓词)的测试,结果为 true(事实存在)或 false(事实不存在)。
因此,应该按照我的答案(命名约定)中的详细说明,为行、事实和谓词命名表(无论如何,它是数据库文档的一部分),但作为单独的谓词列表。
这并不是说它们不重要。它们非常重要,但我不会在这里写下来。
那就快点吧。由于关系模型是建立在FOPC之上的,所以整个数据库可以说是一组FOPC声明,一组Predicates。但是(a)有多种类型的谓词,(b)一张表并不代表一个谓词(它是许多谓词的物理实现,并且具有不同的类型谓词)。
因此,将表命名为它“代表”的“the”谓词是一个荒谬的概念。
“理论家”只知道几个谓词,他们不明白,由于 rm 是在FOL上建立的,因此整个数据库是一组谓词,并且具有不同的类型。
当然,他们从他们所知道的少数人中选择荒谬的人:
ascome_person
;person_is_called
。如果不是那么难过,那会很有趣。还请注意,标准表名称名称(命名行)非常适合所有词汇(包括附加到表上的所有谓词)。相反,“表代表谓词”名称不能,这对“理论家”来说是很好的,他们对谓词很少了解,但没有其他理解。
与数据模型相关的谓词在的模型中表达,它们是两个顺序。
。
第一组是图表,而不是文本:符号本身。这些包括各种存在;面向约束;和描述符(属性)谓词。
第二组是事实之间形成关系的。这是关系线。动词短语(上面详细介绍)标识已实现的谓词命题(可以通过查询进行测试)。一个人不能比这更明确。
因此,对于一个流利的标准数据模型的人来说,所有相关的谓词在模型中都记录在模型中。他们不需要单独的谓词列表(但是无法从数据模型中“读取”所有内容的用户做!)
。
这是 ,我列出了谓词。我之所以选择该示例,是因为它显示了存在等,谓词以及关系,唯一未列出的谓词是描述符。在这里,由于寻求者的学习水平,我将他视为用户。
因此,在两个父表之间有多个子表的事件不是问题,只需将它们命名为其内容,并将其标准化。
我为关联表的关系名称提供的动词短语提供的规则在这里发挥作用。这是 讨论,涵盖了所有提到的观点。
对于很好的简短说明,请正确使用谓词以及如何使用它们(这与此处回应评论的情况完全不同),请访问 此答案 ,然后向下滚动到谓词部分。
ok,这就是我们所说的键或nextKey表。这样命名。如果您患有主题,请使用com_nextkey表示在整个数据库中很常见。
顺便说一句,这是一种生成钥匙的非常差的方法。根本不可扩展,但是随着Oracle的性能,它可能“很好”。此外,这表明您的数据库充满了替代物,在这些领域不相关。这意味着表现极差和缺乏正直。
Table • Name
Yes. Plural in the table names are a sure sign of someone who has not read any of the standard materials and has no knowledge of database theory.
Some of the wonderful things about Standards are:
debate them.
The standard table name refers to each row in the table, which is used in the all verbiage, not the total content of the table (we know that the
Customer
table contains all the Customers).Relationship, Verb Phrase
In genuine Relational Databases that have been modelled (as opposed to pre-1970's Record Filing Systems [characterised by
Record IDs
which are implemented in an SQL database container for convenience):[**Diagram_A**][Diagram_A]
Of course, the relationship is implemented in SQL as a
CONSTRAINT FOREIGN KEY
in the child table (more, later). Here is the Verb Phrase (in the model), the Predicate that it represents (to be read from the model), and the FK Constraint Name:Table • Language
However, when describing the table, particularly in technical language such as the Predicates, or other documentation, use singular and plurals as they naturally in the English language. Keeping in mind the table is named for the single row (relation) and the language refers to each derived row (derived relation):
not
(That is not a naming-convention question; that is a db design question.) It doesn't matter if
user::product
is 1::n. What matters is whetherproduct
is a separate entity and whether it is an Independent Table, ie. it can exist on its own. Thereforeproduct
, notuser_product
.And if
product
exists only in the context of anuser
, ie. it is a Dependent Table, thereforeuser_product
.[**Diagram_B**][Diagram_B]
That's right. Either
user_product_description
xorproduct_description
will be correct, based on the above. It is not to differentiate it from otherxxxx_descriptions
, but it is to give the name a sense of where it belongs, the prefix being the parent table.Hopefully all the tables in the relational database are pure relational, normalised tables. There is no need to identify that in the name (otherwise all the tables will be
rel_something
).If it contains only the PKs of the two parents (which resolves the logical n::n relationship that does not exist as an entity at the logical level, into a physical table), that is an Associative Table. Yes, typically the name is a combination of the two parent table names.
Note that is such cases the Verb Phrase applies to, and is read as, from parent to parent, ignoring the child table, because its only purpose in life is to relate the two parents.
[**Diagram_C**][Diagram_C]
If it is not an Associative Table (ie. in addition to the two PKs, it contains data), then name it appropriately, and the Verb Phrases apply to it, not the parent at the end of the relationship.
[**Diagram_D**][Diagram_D]
If you end up with two
user_product
tables, then that is a very loud signal that you have not normalised the data. So go back a few steps and do that, and name the tables accurately and consistently. The names will then resolve themselves.Naming Convention
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 kind of 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. 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
UpdatedDate
if it is aDATETIME
datatype, useUpdatedDtm
. Do not use_description
if it contains a dosage.It is important to be consistent across the database. Do not use
NumProduct
in one place to indicate number of Products andItemNo
orItemNum
in another place to indicate number of Items. UseNumSomething
for numbers-of, andSomethingNo
orSomethingId
for identifiers, consistently.Do not prefix the column name with a table name or short code, such as
user_first_name
. SQL already provides for the tablename as a qualifier: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
user_id
, neverid
.user_id
is the column that identifies an user, not theid
of theuser
table.user_product
table will have anuser_id
as a component of its PK(user_id, product_no)
.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.
AssemblyCode
andComponentCode
for twoPartCodes
. And in that case, do not use the undifferentiatedPartCode
for one of them. Be precise.Diagram_E
Prefix
Where you have more than say 100 tables, prefix the table names with a Subject Area:
REF_
for Reference tablesOE_
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:
_V
View (with the mainTableName
in front, of course)_fk
Foreign Key (the constraint name, not the column name)_cac
Cache_seg
Segment_tr
Transaction (stored proc or function)_fn
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:
____
blah blah blah error on object_name
you know exactly what object was violated, and what it was trying to do:
____
blah blah blah error on Customer_Add_tr
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).
Customer_Initiates_SalesOrder_fk
Part_Comprises_Component_fk
Part_IsConsumedIn_Assembly_fk
Use the
Parent_Child_fk
sequence, notChild_Parent_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:____
Foreign key violation on Vendor_Offers_PartVendor_fk
.That works well for people who model their data, where the Verb Phrases have been identified. For the rest, the record filing systems, etc, use
Parent_Child_fk
.U
Unique, or_
for non-uniqueC
Clustered, or_
for non-clustered_
separatorFor the remainder:
- If the key is one column or a very few columns:
____
ColumnNames
____
PK
Primary Key (as per model)____
AK[*n*]
Alternate Key (IDEF1X term)Note that the table name is not required in the index name, because it always shows up as
table_name.index_name.
So when
Customer.UC_CustomerId
orProduct.U__AK
appears in an error message, it tells you something meaningful. When you look at the indices on a table, you can differentiate them easily.Order Entry & Inventory with Standard-compliant Addresses
Simple inter-office Bulletin system for PHP/MySQL
Sensor Monitoring with full Temporal capability
Answers to Questions
That cannot be reasonably answered in the comment space.
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).
(Or, AssemblyComponent, for those who realise that one fact identifies the other)
Now that I have resolved the tables, I don't understand your problem. Perhaps you can post a specific question.
Predicate
Assuming there are no Normalisation errors,
User likes Product
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). Predicates (or propositions), are not Facts, they may or may not be true.
The Relational Model is based on First Order Predicate Calculus (more commonly known as First Order Logic). A Predicate is a single-clause sentence in simple, precise English, that evaluates to true or false.
Further, each table represents, or is the implementation of, many Predicates, not one.
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 FOPC, the entire database can be said to be a set of FOPC declarations, a set of Predicates. But (a) there are many types of Predicates, and (b) a table does not represent one 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 "table represents predicate" name cannot, which is fine for the "theoreticians", who understand very little about Predicates, but not otherwise.
The Predicates that are relevant to the data model, are expressed in the model, they are of two orders.
The first set is diagrammatic, not text: the notation itself. These include various Existential; Constraint-oriented; and Descriptor (attributes) Predicates.
The second set is those that form relationships between Facts. This is the relation 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, who cannot 'read' everything from the data model, 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 relationship names for Associative Tables come into play here. Here is a Predicate vs Table discussion, covering all points mentioned, in summary.
For a good short description re the proper use of Predicates and how to use them (which is quite a different context to that of responding to comments here), visit this answer, and scroll down to the Predicate section.
Ok, that is what we call a Key or NextKey table. Name it as such. If you have SubjectAreas, use COM_NextKey to indicate it is common across the database.
Btw, that is a very poor method of generating keys. Not scalable at all, but then with Oracle's performance, it is probably "just fine". Further, it indicates that your database is full of surrogates, not relational in those areas. Which means extremely poor performance and lack of integrity.
单数与复数:选择一个并坚持使用。
列不应带有前缀/后缀/中固定或以任何方式通过引用它是列这一事实来固定。桌子也是如此。不要将表命名为 EMPLOYEE_T 或 TBL_EMPLOYEES,因为当它被视图替换时,事情会变得非常混乱。
不要在名称中嵌入类型信息,例如 varchar 的“vc_firstname”或“flavour_enum”。也不要在列名称中嵌入约束,例如“department_fk”或“employee_pk”。
实际上,我能想到的关于 *fixes 的唯一好处是,您可以使用保留字,例如
where_t
、tbl_order
、user_vw
。当然,在这些示例中,使用复数可以解决问题:)不要将所有键命名为“ID”。引用同一事物的键在所有表中应具有相同的名称。用户 id 列在用户表和引用该用户的所有表中可以称为 USER_ID。唯一一次重命名是当不同的用户扮演不同的角色时,例如Message(sender_user_id,receiver_user_id)。这在处理较大的查询时确实很有帮助。
关于CaSe:
一般来说,最好命名“映射表”以匹配它描述的关系,而不是引用表的名称。用户可以与产品有任意数量的关系:
user_likes_product
、user_bought_product
、user_wants_to_buy_product
。Singular vs. Plural: Pick one and stick with it.
Columns shouldn't be prefixed/suffixed/infixed or in anyway fixed with references to the fact that it is a column. The same goes for tables. Don't name tables EMPLOYEE_T or TBL_EMPLOYEES because the second it is replaced with a view, things get really confusing.
Don't embed type information in names, such as "vc_firstname" for varchar, or "flavour_enum". Also don't embed constraints in column names, such as "department_fk" or "employee_pk".
Actually, the only good thing about *fixes I can think of, is that you can use reserved words like
where_t
,tbl_order
,user_vw
. Of course, in those examples, using plural would have solved the issue :)Don't name all keys "ID". Keys refering to the same thing, should have the same name in all tables. The user id column could be called USER_ID in the user table and all tables referencing the user. The only time it is renamed is when different users are playing different roles, such as Message(sender_user_id, receiver_user_id). This really helps when dealing with larger queries.
Regarding CaSe:
In general it is better to name "mapping tables" to match the relation it describes rather than the names of the referenced tables. A user can have any number of relations to products:
user_likes_product
,user_bought_product
,user_wants_to_buy_product
.单数和复数之间没有“正确”之分——这主要是一个品味问题。
这部分取决于您的关注点。如果您将表视为一个单元,那么它包含“复数”(因为它包含许多行 - 因此复数名称是合适的)。如果您将表名视为标识表中的行,那么您会更喜欢“单数”。这意味着您的 SQL 将被视为处理表中的一行。没关系,尽管这通常过于简单化了。 SQL 适用于集合(或多或少)。然而,我们可以用单数来回答这个问题。
由于您可能需要一个表“用户”,另一个“产品”,第三个表将用户连接到产品,因此您需要一个表“user_product”。
由于说明适用于产品,因此您可以使用“product_description”。除非每个用户为自己的每个产品命名...
“user_product”表是(或可能是)具有产品 ID 和用户 ID 的表的示例,仅此而已。您可以使用相同的通用方式命名两个属性表:“user_stuff”。像“rel_”这样的装饰性前缀并没有真正的帮助。例如,您会看到有些人在每个表名称前面使用“t_”。这没什么帮助。
There is no 'correct' about singular vs plural - it is mostly a matter of taste.
It depends in part on your focus. If you think of the table as a unit, it holds 'plurals' (because it holds many rows - so a plural name is appropriate). If you think of the table name as identifying a row in a table, you'll prefer 'singular'. This means your SQL will be thought of as working on one row from the table. That's OK, though it is usually an oversimplification; SQL works on sets (more or less). However, we can go with singular for the answers to this question.
Since you'll probably need a table 'user', another 'product', and the third to connect users to products, then you need a table 'user_product'.
Since the description applies to a product, you would use 'product_description'. Unless each user names each product for themselves...
The 'user_product' table is (or could be) an example of a table with a product ID and a user ID and not much else. You name the two-attribute tables in the same general way: 'user_stuff'. Decorative prefixes like 'rel_' don't really help. You'll see some people using 't_' in front of each table name, for instance. That is not a lot of help.
只要一致使用,复数就不错——但我更喜欢单数。
除非您想概述多对多关系,否则我会省略下划线;并使用初始大写字母,因为它有助于区分 ORM 中的事物。
但是有很多命名约定,因此如果您想使用下划线,只要保持一致就可以。
所以:
如果只有一个用户可以拥有任何产品,那么
但是如果该产品由用户共享:
如果您为多对多关系保存下划线,您可以执行以下操作:
在 UserProduct 和 Stuff 之间形成 M-to-M - 从问题中不确定所需的多对多的确切性质。
Plurals aren't bad as long as they are used consistently - but singular is my preference.
I would dispense with underscores unless you want to outline a many-to-many relationship; and use an initial capital because it helps distinguish things in ORMs.
But there are many naming conventions, so if you want to use underscores that's OK as long as its done consistently.
So:
If only one user can have any product then
But if the product is shared by users:
If you save your underscores for many-to-many relationships you can do something like:
to form a M-to-M between UserProduct and Stuff - not sure from the question the exact nature of the many-to-many required.
使用单数形式没有比使用复数形式更正确的了,您从哪里听说过?我宁愿说复数形式对于命名数据库表来说更常见......并且在我看来也更逻辑。该表通常包含不止一行;)在概念模型中,尽管实体的名称通常是单数。
关于您的问题,如果“产品”和“产品描述”是模型中具有身份(即实体)的概念,我将简单地将表称为“产品”和“产品描述”。对于用于实现多对多关系的表,我最常使用命名约定“SideA2SideB”,例如“Student2Course”。
There is not more correct to use singular than plural form, where have you heard that? I would rather say that plural form is more common for naming database tables...and in my opinion also more logic. The table most often contain more than one row ;) In a conceptual model though the names of the entities are often in singular.
About your question, if 'Product' and 'ProductDescription' are concepts with an identity (i.e. entities) in your model I would simply call the tables 'Products' and 'ProductDescriptions'. For tables that are used in order to implement a many-to-many relationship I most often use the naming convention "SideA2SideB", for example "Student2Course".