mysql主键外键_MySQL主键和外键使用及说明
摘自網(wǎng)上一個(gè)經(jīng)典的例子:大哥和小弟
一、外鍵約束
MySQL通過(guò)外鍵約束來(lái)保證表與表之間的數(shù)據(jù)的完整性和準(zhǔn)確性。
外鍵的使用條件:
1.兩個(gè)表必須是InnoDB表,MyISAM表暫時(shí)不支持外鍵(據(jù)說(shuō)以后的版本有可能支持,但至少目前不支持);
2.外鍵列必須建立了索引,MySQL 4.1.2以后的版本在建立外鍵時(shí)會(huì)自動(dòng)創(chuàng)建索引,但如果在較早的版本則需要顯示建立;
3.外鍵關(guān)系的兩個(gè)表的列必須是數(shù)據(jù)類型相似,也就是可以相互轉(zhuǎn)換類型的列,比如int和tinyint可以,而int和char則不可以;
外鍵的好處:可以使得兩張表關(guān)聯(lián),保證數(shù)據(jù)的一致性和實(shí)現(xiàn)一些級(jí)聯(lián)操作;
外鍵的定義語(yǔ)法:
[constraint symbol] foreign key [id] (index_col_name, ...)
references tbl_name (index_col_name, ...)
[on delete {restrict | cascade | set null | on action | set default}]
[on update {restrict | cascade | set null | on action | set default}]
該語(yǔ)法可以在 create table 和 alter table 時(shí)使用,如果不指定constraint symbol,MYSQL會(huì)自動(dòng)生成一個(gè)名字。
on delete,on update表示事件觸發(fā)限制,可設(shè)參數(shù):
restrict(限制外表中的外鍵改動(dòng))
cascade(跟隨外鍵改動(dòng))
set null(設(shè)空值)
set default(設(shè)默認(rèn)值)
no action(無(wú)動(dòng)作,默認(rèn)的)
1. 先建立1個(gè)新的數(shù)據(jù)庫(kù)
2.在pycharm中新建2張table(Dage,Xiaodi)
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
engine=create_engine("mysql+pymysql://root:1234@localhost/chen")
Base=declarative_base()
class Dage(Base):
__tablename__='Dage'
id=Column(Integer,primary_key=True)
name=Column(String(32))
class Xiaodi(Base):
__tablename__='Xiaodi'
id=Column(Integer,primary_key=True)
name=Column(String(32))
Dage_id = Column(Integer,ForeignKey('Dage.id'))Base.metadata.create_all(engine)
在客戶端show table已經(jīng)創(chuàng)建過(guò)程
show create table xiaodi;
----------------------------------------------------------------------+
| xiaodi | CREATE TABLE `xiaodi` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`Dage_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `Dage_id` (`Dage_id`),
CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`Dage_id`) REFERENCES `dage` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
show create table dage;
3.在2張表中各插入1條數(shù)據(jù)。由于不知名的錯(cuò)誤,需要把2個(gè)表中的數(shù)據(jù)分開(kāi)創(chuàng)建。
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from sqlalchemy.orm import sessionmaker
engine=create_engine("mysql+pymysql://root:1234@localhost/chen")
Base=declarative_base()
class Dage(Base):
__tablename__='Dage'
id=Column(Integer,primary_key=True)
name=Column(String(32))
class Xiaodi(Base):
__tablename__='Xiaodi'
id=Column(Integer,primary_key=True)
name=Column(String(32))
Dage_id = Column(Integer,ForeignKey('Dage.id'))
Base.metadata.create_all(engine)
Session_class=sessionmaker(bind=engine)
session=Session_class()
#dage1=Dage(name='I_am_dage')
xiaodi1=Xiaodi(Dage_id=1,name='I_am_xiaodi')
session.add_all([xiaodi1])
session.commit()
查看效果:發(fā)現(xiàn)這種創(chuàng)建方式有個(gè)問(wèn)題,id會(huì)自增,2張表的ID依次為1,2
4.嘗試刪除大哥
刪除不了,因?yàn)橛型怄I約束
插入1個(gè)小弟,因?yàn)闆](méi)有大哥,所以插入不成功
5.把外鍵約束增加事件觸發(fā)限制:
alter table xiaodi drop foreign key xiaodi_ibfk_1;
alter table xiaodi add foreign key(Dage_id) references dage(id) on delete cascade on update cascade; #意思是從表會(huì)跟隨主表的改變而改變。
理論上,現(xiàn)在就能正常刪除了。
二,多外鍵關(guān)聯(lián)
建立一個(gè)customer表和一個(gè)地址表
表結(jié)構(gòu):
from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()
class Customer(Base):
__tablename__ = 'customer'
id = Column(Integer, primary_key=True)
name = Column(String(64))
# 賬單地址和郵寄地址 都關(guān)聯(lián)同一個(gè)地址表
billing_address_id = Column(Integer, ForeignKey("address.id"))
shipping_address_id = Column(Integer, ForeignKey("address.id"))
billing_address = relationship("Address", foreign_keys=[billing_address_id])
shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
city = Column(String(64))
def __repr__(self):
return self.street
engine = create_engine("mysql+pymysql://root:1234@localhost/chen",
encoding='utf-8')
Base.metadata.create_all(engine) # 創(chuàng)建表結(jié)構(gòu)
生成表內(nèi)容:
from Day12 import ex5
from sqlalchemy.orm import sessionmaker
Session_class = sessionmaker(bind=ex5.engine) # 創(chuàng)建與數(shù)據(jù)庫(kù)的會(huì)話session class ,注意,這里返回給session的是個(gè)class,不是實(shí)例
session = Session_class() # 生成session實(shí)例 #cursor
addr1 = ex5.Address(city="BJ")
addr2 = ex5.Address(city="Shanghai")
addr3 = ex5.Address(city="Tianjin")
session.add_all([addr1, addr2, addr3])
c1 = ex5.Customer(name="Alex", billing_address=addr1, shipping_address=addr2)
c2 = ex5.Customer(name="Jack", billing_address=addr3, shipping_address=addr3)
session.add_all([c1, c2])
session.commit()
效果:
查詢:
obj=session.query(ex5.Customer).filter(ex5.Customer.name=='Alex').first()
print(obj.name,obj.billing_address,obj.shipping_address)
返回結(jié)果:
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day12/ex4.py
Alex BJ Shanghai
Process finished with exit code 0
三,多對(duì)多
1.創(chuàng)建表結(jié)構(gòu)
import sqlalchemy
from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Base=declarative_base()
book_m2m_author=Table('book_m2m_author',Base.metadata,
Column('book_id',Integer,ForeignKey('books.id')),
Column('author_id',Integer,ForeignKey('authors.id')),
)
class Book(Base):
__tablename__='books'
id=Column(Integer,primary_key=True)
name=Column(String(64))
authors=relationship('Author',secondary=book_m2m_author,backref='books')
def __repr__(self):
return self.name
class Author(Base):
__tablename__='authors'
id=Column(Integer,primary_key=True)
name=Column(String(32))
def __repr__(self):
return self.name
engine=create_engine('mysql+pymysql://root:1234@localhost/chen')
Base.metadata.create_all(engine)
2. 增加表內(nèi)容
# 添加數(shù)據(jù)
from Day12 import ex4
from sqlalchemy.orm import sessionmaker
Session_class = sessionmaker(bind=ex4.engine) # 創(chuàng)建與數(shù)據(jù)庫(kù)的會(huì)話session class ,注意,這里返回給session的是個(gè)class,不是實(shí)例
session = Session_class() # 生成session實(shí)例 #cursor
# 創(chuàng)建書(shū)
b1 = ex4.Book(name="learn python with Alex")
b2 = ex4.Book(name="learn Zhangbility with Alex")
b3 = ex4.Book(name="Learn hook up girls with Alex")
# 創(chuàng)建作者
a1 = ex4.Author(name="Alex")
a2 = ex4.Author(name="Jack")
a3 = ex4.Author(name="Rain")
# 關(guān)聯(lián)關(guān)系
b1.authors = [a1, a3]
b3.authors = [a1, a2, a3]
session.add_all([b1, b2, b3, a1, a2, a3])
session.commit()
查看效果:
3. 通過(guò)作者查詢書(shū)
4.通過(guò)書(shū)查作者
總結(jié)
以上是生活随笔為你收集整理的mysql主键外键_MySQL主键和外键使用及说明的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据优化:求求你别再用offset和li
- 下一篇: Redis 怎么防止数据丢失?面试必问!