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适合开发。
微信分享/微信扫码阅读