MySQL数据库关系表的设计

MySQL的关联主要通过外键来实现,主要关系有一对一,一对多,多对多等等。有了关联表我们可以多个表分类的存储数据,比较清晰

MySQL的外键必须来源于另外一张表的主键,有了外键约束,可以在多个表中自动更新。

创建一对多:


MySQL语句

User表:


create table User ( id int(4) PRIMARY KEY AUTO_INCREMENT ,
                                role varchar(10) not null,
                                email varchar(64) not null)


Articles表:

create table Articles( id int(4) PRIMARY KEY AUTO_INCREMENT ,
                                author_id int(4) not null
                                create_time timestamp,
                                FOREIGN KEY (author_id) references (User.id))ENGINE=INNODB AUTO_INCEREMENT=2 DEFAULT CHARSET=UTF8

如上两个关系表的建立,通过外键author_id联系了起来。

针对一对多见如下示例(来源于我的Flask项目):



class User(db.Model):

    __tablename__ = 'users'
    query_class = UserQuery

    id = db.Column(db.Integer,primary_key=True)  
    username = db.Column(db.String(60),unique=True,nullable=False)
    password_hash = db.Column(db.String(128))
    last_visit_time = db.Column(db.DateTime,default = datetime.utcnow)
    #.....

class Article(db.Model):

    __tablename__ = 'articles'

    query_class = ArticleQuery

    id = db.Column(db.Integer,primary_key=True)
    author_id = db.Column(db.Integer,db.ForeignKey(User.id,ondelete='CASCADE'))
    author = relationship(User,backref=backref('articles',order_by=id))
    title = db.Column(db.String(128),unique=True)
 

在Article表中设置: author = relationship(User,backref=backref('articles',order_by=id))backref提供了一种反向引用,我们可以直接使用User.articles属性,这种方法非常方便。

Django项目:

class Category(models.Model):

    name = models.CharField(max_length=150,unique=True,verbose_name=u'类名')



class Article(models.Model):

    title = models.CharField(max_length=150,unique=True,verbose_name=u'标题')
    category = models.ForeignKey(Category,verbose_name=u'分类')

Django中通过ForeignKey建立了一对多的关系表。一个category可以对多篇文章,多篇文章只可以有一个category。

一对多可能是我们最经常用的了。

 

一对一关系:建立一对一关系,我觉得就是在一对多的前提下设立了一个唯一健,即在上面的MySQL语句中的user_id加一个unique就可以了。在Django中,我们通过OneToOneField字段实现一对一的关系。我在项目里也使用了:

class UserProfile(models.Model):
    ..................
    user = models.OneToOneField(User)

UserProfile用来存储用户的其他信息,他和User表中的数据肯定是要形成一对一关系的,一个人只能对应一个啊。上面是ORM,下面是通过SQL语句:

User表:


create table User ( id int(4) PRIMARY KEY AUTO_INCREMENT ,
                                role varchar(10) not null,
                                email varchar(64) not null)


Articles表:

create table Articles( id int(4) PRIMARY KEY AUTO_INCREMENT ,
                                author_id int(4) not null,
                                create_time timestamp,
                                UNIQUE KEY (`author_id`),
                                FOREIGN KEY (author_id) references `User` (`id`)
                            )

多对多关系: 在Flask中,建立多对多关系表时,要借用第三张辅助表,有了辅助表,两张表可以形成多对多的关系。实际应用中,我们经常遇到多对多关系,即一篇文章可以有多个标签,一个标签也可以对应多篇文章;在Django中使用ManyToManyField字段

多对多我觉得不是特别常用啊!

 

最后摘抄一下,对外键的要求:
1. FOREIGN KEY 约束是大多数(但不是所有)的关系型数据库中可以链接到主键列,或者拥有UNIQUE约束的列。
2. FOREIGN KEY 能够引用多重列主键,并且其自身拥有多重列,被称为“复合外键”(composite foreign key)。其也能够引用这些列的子集(subset)。(注:这地方不太明白)
3. FOREIGN KEY 列作为对于其引用的列或者行的变化的响应能够自动更新其自身,比如CASCADE引用操作,这些都是内置于关系型数据库的功能之一。
4. FOREIGN KEY 能够引用其自身的表,这个就涉及到“自引用”(self-referential)的外键了。

 

 

最后说一句题外话:Django真的比Flask好用,方便多了,Flask适合学习,Django适合开发。

--------EOF---------
本文微信分享/扫码阅读