05.实体关系

作者: gthank | 来源:发表于2020-05-09 16:07 被阅读0次

05.实体关系

实体之间可以相互关联,两个实体之间的关系是由两个属性来定义的,这两个属性指定了关系的两端:

class Customer(db.Entity):
    orders = Set('Order')

class Order(db.Entity):
    customer = Required(Customer)

在上面的例子中,我们有两个关系属性:orderscustomer,当我们定义实体Customer时,实体Order还没有定义,这就是为什么我们要在订单属性中的订单周围加上引号。

另一种方法是使用lambda:

class Customer(db.Entity):
    orders = Set(lambda: Order)

如果你想让你的IDE检查声明的实体名称并高亮显示错别字,这可能很有用。

一些映射器 (例如 Django) 只要求在一侧定义关系,Pony 要求在两边显式地定义关系 (正如《Python之禅》中所说:显式比隐式更好),这使得用户可以从每个实体的角度看所有的关系。

所有的关系都是双向的。如果你更新了一个关系的一边,另一边也会自动更新。例如,如果我们创建了一个订单实体Order的实例,客户的订单集将被更新至包含这个新订单。

关系有三种类型:一对一、一对多和多对多关系。一对一的关系很少使用,大多数实体之间的关系是一对多和多对多的关系。

如果两个实体之间有一对一的关系,那往往意味着它们可以组合成一个实体。

如果你的数据图有很多一对一的关系,那么这可能是你需要重新考虑实体定义的信号。

个人意见:这个需要根据实际需求来定,如果一个表很宽(字段很多),这时候可以根据业务及使用频率,考虑将其拆分为多个表——gthank

一对多的关系

下面是一个单对多关系的例子:

class Order(db.Entity):
    items = Set("OrderItem")

class OrderItem(db.Entity):
    order = Required(Order)

在上面的例子中,没有订单,OrderItem的实例就不能存在。如果我们想让OrderItem的实例不被分配给一个订单而存在,我们可以将订单属性定义为Optional:

class Order(db.Entity):
    items = Set("OrderItem")

class OrderItem(db.Entity):
    order = Optional(Order)

多对多的关系

为了创建多对多关系,你需要将关系的两端定义为Set属性。

class Product(db.Entity):
    tags = Set("Tag")

class Tag(db.Entity):
    products = Set(Product)

为了在数据库中实现这种关系,Pony将创建一个中间表。这是一个众所周知的解决方案,可以让你在关系型数据库中拥有多对多关系。

一对一关系

为了创建一对一的关系,应该将关系属性定义为Optional-RequiredOptional-Optional

class Person(db.Entity):
    passport = Optional("Passport")

class Passport(db.Entity):
    person = Required("Person")

不允许将这两个属性定义为必填,因为这样做没有意义。

自我引用

一个实体可以使用自我参照关系与自身建立关系。这种关系可以分为两种类型:对称关系和非对称关系。

非对称关系是由属于同一实体的两个属性定义的。

对称关系的具体情况是,实体只指定了一个关系属性,而这个属性定义了关系的双方。这种关系可以是一对一的关系,也可以是多对多的关系。下面是自引用关系的例子。

class Person(db.Entity):
    name = Required(str)
    spouse = Optional("Person", reverse="spouse") # 对称的一对一
    friends = Set("Person", reverse="friends")    # 对称的多对多
    manager = Optional("Person", reverse="employees") # 非对称的一面
    employees = Set("Person", reverse="manager") # 非对称的另一面

两个实体之间的多重关系

当两个实体之间有一个以上的关系时,Pony需要指定反向属性,这样做的目的是为了让Pony知道哪一对属性之间有关系。

让我们考虑一下这个数据图,在这个数据图中,用户可以写推文,也可以收藏推文:

class User(db.Entity):
    tweets = Set("Tweet", reverse="author")
    favorites = Set("Tweet", reverse="favorited")

class Tweet(db.Entity):
    author = Required(User, reverse="tweets")
    favorited = Set(User, reverse="favorites")

在上面的例子中,我们必须指定反向选项。如果你试图为实体定义生成映射而不指定反向属性,你会得到异常pony.orm.core.erDiagramError: "Ambiguous reverse attribute for Tweet.author"

之所以出现这种情况,是因为属性author在技术上可以与tweetsfavorites相关,而Pony没有任何信息说明应该使用哪个属性。

相关文章

  • 05.实体关系

    05.实体关系 实体之间可以相互关联,两个实体之间的关系是由两个属性来定义的,这两个属性指定了关系的两端: 在上面...

  • ER图

    实体1(长方形) --- 关系(菱形) --- 实体2(长方形) 实体关系都是表 细线:一个实体-...

  • asp.net core系列 26 EF模型配置(实体关系)

    一.概述 EF实体关系定义了两个实体互相关联起来(主体实体和依赖实体的关系,对应数据库中主表和子表关系)。 在关系...

  • 实体关系

    1 : 1 设计 例如:一个学生对应一个座位 在一个表中存在一个与另一个表的主键相同的主键 1 : n 例如:一个...

  • 数据库(二)2018-08-24

    1. MySQL是一个关系型数据库, 关系型数据库描述的就是实体与实体之间的关系.聊到实体与实体之间的关系(表与表...

  • 09.处理实体关系

    09.处理实体关系 在Pony中,一个实体可以通过关系属性与其他实体建立关系,每个关系总是有两端,并且由两个实体属...

  • 实体关系抽取

    实体属性关系抽取 针对语料:通用语料 抽取关系:通用实体关系 抽取级别:句子级别 关系类型(通用文本) 关系类型(...

  • Udacity 商业数据分析课程笔记

    数据库原理与SQL基础 实体关系图 实体关系图 (entity relationship diagram,ERD)...

  • E-R模型

    两个实体之间的关系: 除了多对一之外的关系都有。 两个以上的实体之间的关系: 除了一对多其他都有。 单个实体的内在...

  • 实体关系抽取

    实体识别的难点,不好建模,比如投资关系: 1.方向:投资方和被投方2.关系多维,错综复杂:投资方有多个,被投资只有...

网友评论

    本文标题:05.实体关系

    本文链接:https://www.haomeiwen.com/subject/ogiknhtx.html