适用于多对多交叉表的表命名约定

Zom*_*ies 31 database-design

我有很多关系:客户端和代理表(只是一个例子).显然,每个客户端可以有多个代理,每个代理可以有多个客户端.什么被认为是交叉表的正确命名约定....是ClientBroker ...?

Fru*_*ner 41

我更喜欢"Clients_Brokers"(将这两个名称复数化以表示多对多).

  • 这是旧的单数与复数表命名冲突(在此扩展为连接表).您是否以单数形式命名表格 - 例如"客户",因为每条记录代表一个客户?或复数,因为表本身包含许多"客户"?这是一个意见问题,我认为没有理由拒绝这一点. (4认同)
  • 我投了这票,因为其他人投了票.我认为这个惯例很好,而且经常是必要的.MVC框架提供的一些ORM库具有表的命名约定,以自动处理关系.我知道至少有3个PHP框架使用复数名称和下划线分隔多对多数据透视表名称,如下所示. (3认同)

小智 18

我更喜欢区分交叉表和实际的事务表.所以,我用Map结束它们.所以它将是Client_Broker_Map或ClientBrokerMap.


Mic*_*odd 12

我通常使用两个连接表的名称.

所以,在你的情况下,ClientBroker.

  • 按字母顺序排列表格也很好!一些框架(laravel)使用此表示法。即`BrokerClient`代替 (2认同)

fro*_*die 9

我经常看到格式"Client_Broker"


wpj*_*ray 6

一些程序员不喜欢多次表名,原因如下:

  • 它打破了"是一个"规则,这意味着如果你有一个名为'User'的表,那么表中的每个记录"都是一个"User对象.这遵循面向对象的规则.
  • Model类通常以其数据来源的表命名.因此,如果您有User模型,则模型所代表的记录位于User表中

如果您控制项目的整个数据库和业务层,这将非常有意义.但是,许多框架现在都有ORM库,可以帮助处理表和关系.这些ORM库通常都有一个命名语法,应该遵循这个命令语法让ORM库完成大部分繁重工作.

例如,我使用PHP的Kohana MVC框架,它提供了一个ORM库.ORM建议使用所有小写名称复数表名,并使用下划线表示多对多表名.因此,对于您的示例,您将拥有以下表:clients,brokers和brokers_clients(ORM建议按字母顺序排列多对多表的表名).在为这些表创建模型(扩展ORM模型)时,使用表名的单数值,因此客户端的模型将是Client.ORM处理复数转换.Kohana的ORM也使用了一个变形库,因此可以正确处理不寻常的复数值.例如,名为"categories"的表可以使用模型名称"Category".最后,


小智 5

我正处于一个项目的中间,我正在使用DESCRIBE获取表和字段名称.我使用Client_x_Broker所以我可以很容易地找到一个表并通过使用_x_作为标准来获取字段,这个字符串在代码或数据集中不会自然地出现,而且无论如何都不在我的中,并且很容易实现找到单个表的名称.此外,只要我保持一致,我就可以从表名中获得大量信息,包括主键名.对不起,迟到了,b,继续.:)


And*_*ver 5

对于Hibernate用户,根据日志消息和分析生成的查询,通过反复试验发现了未记录的规则:

在此输入图像描述

形式化此图,您需要使用名为:table1_table2 的链接表,并在链接表中使用如下所示的 ids:table1_table1Id 和 table2_table2Id

通过这样做,Hibernate 无需进一步解释并提供 @JoinTable 信息即可了解正在发生的情况。

@Data
@Entity
@Table(name="course")
public class Course {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long courseId;

    @Column(name="name")
    private String name;
}

@Data
@Entity
@Table(name="student")
public class Student {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long studentId;

    @Column(name="name")
    private String name;

    @Column(name="class")
    private String className;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private List<Course> course;
}
Run Code Online (Sandbox Code Playgroud)

如果您坚持此映射,所有 JPQL 查询都会顺利工作,并按预期生成带有外连接的正确 SQL 查询...注意,当然最后没有-s !如果你想要课程,应该将连接表中的字段名称更改为 table2 s _table2Id 并将表本身更改为 table2 s

PS我在 JPA 和 Hibernate 文档中都没有发现任何关于此约定的直接提及(仅在单个示例中),并且它可能会在未来版本中进行更改,并使用 Hibernate 5.2/5.3 进行测试。然而,它给出了如何命名连接表和其中的字段的提示。


小智 5

我更喜欢能够解释表中实体之间关系的联结表名称。在这种情况下,我可以将该表称为“client_has_broker”或“broker_has_client”。

除了明确关系是什么(诸如“client_broker”和“broker_x_client”之类的东西不会告诉您实体如何相关 - 客户端是否与经纪人合作,或者客户端是否吃掉了经纪人?),这允许您拥有以不同方式关联相同实体的其他联结表 - 例如“client_hates_broker”或“broker_bankrupted_client”。

至于单数与复数问题 - 即使这是一个多对多关系,表中的每一行仍然只引用一个关系,所以我总是使用单数名称(例如“client_has_broker”,而不是“客户拥有经纪人”)。这样,无论您从查询中获得多少结果,该名称都有意义。(“这个客户有这 5 个 client_has_broker 关系”对我来说比“这个客户有这 5 个 client_to_brokers 关系”更有意义。)

显然有一百万种不同的方法 - 我已经尝试了其中的很多 - 但对我来说,这是最简单和最清晰的命名约定。