日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql主键外键_MySQL主键和外键使用及说明

發(fā)布時(shí)間:2023/12/10 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql主键外键_MySQL主键和外键使用及说明 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

摘自網(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。