實(shí)驗(yàn)三:數(shù)據(jù)庫(kù)系統(tǒng)開發(fā)
一骚秦、實(shí)驗(yàn)?zāi)康募耙?/h3>
(一) 實(shí)驗(yàn)?zāi)康?/h4>
在熟練掌握MySQL基本命令她倘、SQL語(yǔ)言以及用C語(yǔ)言編寫MySQL操作程序的基礎(chǔ)上璧微,學(xué)習(xí)簡(jiǎn)單數(shù)據(jù)庫(kù)系統(tǒng)的設(shè)計(jì)方法,包括數(shù)據(jù)庫(kù)概要設(shè)計(jì)硬梁、邏輯設(shè)計(jì)前硫。
(二) 實(shí)驗(yàn)要求
- 該系統(tǒng)的E-R圖至少包括8個(gè)實(shí)體和7個(gè)聯(lián)系(必須有一對(duì)一聯(lián)系、一對(duì)多聯(lián)系荧止、多對(duì)多聯(lián)系)屹电。
- 在設(shè)計(jì)的關(guān)系中需要體現(xiàn)關(guān)系完整性約束:主鍵約束、外鍵約束跃巡,空值約束危号。
- 對(duì)幾個(gè)常用的查詢創(chuàng)建視圖、并且在數(shù)據(jù)庫(kù)中為常用的屬性(非主鍵)建立索引素邪。
- 該系統(tǒng)功能必須包括:插入外莲、刪除、連接查詢娘香、嵌套查詢苍狰、分組查詢。其中插入烘绽,刪除操作需體現(xiàn)關(guān)系表的完整性約束淋昭,例如插入空值、重復(fù)值時(shí)需給予提示或警告等安接。
- 加分項(xiàng):界面友好翔忽、包含事務(wù)管理、觸發(fā)器等功能盏檐。
二歇式、實(shí)驗(yàn)環(huán)境
- 操作系統(tǒng):windows 10
- 數(shù)據(jù)庫(kù):MySql 5.5.29
- 高級(jí)語(yǔ)言:python 3.5
- 網(wǎng)站設(shè)計(jì):django-1.8
三、實(shí)驗(yàn)內(nèi)容
這一部分的目錄如下:
- 用戶需求
- 概念設(shè)計(jì)
- 邏輯設(shè)計(jì)
- 觸發(fā)器和事務(wù)管理
- 具體實(shí)現(xiàn)(MySql)
- 界面設(shè)計(jì)(django)
(一) 用戶需求
這是一個(gè)關(guān)于音樂的數(shù)據(jù)庫(kù)[1]胡野。有以下需求
(1) 歌曲的屬性有:名稱材失、發(fā)布日期、時(shí)長(zhǎng)硫豆、風(fēng)格龙巨、演唱者、作詞人熊响、作曲人 旨别、所屬的專輯。
(2) 演唱者可以是歌手汗茄,也可以是組合秸弛。組合中的成員由歌手組成。歌手的屬性有:名字、性別递览、地區(qū)和所屬的唱片公司叼屠。組合的屬性有:名字、地區(qū)和所屬的唱片公司非迹。
(3) 專輯的屬性有:名字环鲤、發(fā)布日期和主打歌。
(4) 公司的屬性有:名字憎兽、建立時(shí)間和地區(qū)。
(5) 作詞人和作曲人的屬性有:姓名吵冒、性別纯命。
(二) 概念設(shè)計(jì)
1.演唱者
上述數(shù)據(jù)庫(kù)系統(tǒng)設(shè)計(jì)的主要困難在于,如何去處理演唱者痹栖。
為了解決這個(gè)問題亿汞,在已有的兩個(gè)實(shí)體——歌手(Singer)和組合(Band)的基礎(chǔ)上,增加了演唱者(Performer)這個(gè)實(shí)體揪阿。然后通過(guò)兩兩之間建立聯(lián)系集疗我,維持它們關(guān)系。如下圖
</img>
2.歌曲與演唱者南捂、作曲人及作詞人
如下圖吴裤,歌曲(Song)與演唱者(Performer)、作曲人(Composer)及作詞人(Lyricist)分別建立聯(lián)系集:SingSong溺健、LyricsBy麦牺、Compose。
</img>
3.演唱者與唱片公司及專輯
如下圖鞭缭,演唱者(Performer)與唱片公司(RecordCompany)和專輯(Album)分別建立聯(lián)系集:CreateAlbum剖膳、WorkOn。
4.歌曲與專輯
如下圖岭辣,歌曲與專輯建立兩個(gè)聯(lián)系集吱晒,分別為:AlbumMember、TitleSong沦童,以表示“歌曲屬于專輯”和“一個(gè)歌曲是專輯的主打歌”這兩個(gè)聯(lián)系仑濒。
</img>
5.總體ER圖
6.功能需求規(guī)格說(shuō)明
查詢數(shù)據(jù)
(1) 根據(jù)名稱查詢歌曲、演唱者搞动、專輯躏精、唱片公司;
(2) 查看歌曲的演唱者鹦肿、作詞人和作曲人矗烛;
(3) 查看演唱者所屬的唱片公司、演唱的所有歌曲和發(fā)布的專輯;
(4) 查看專輯中的所有的音樂和主打歌瞭吃;
(5) 查看一個(gè)唱片公司中所有的組合和歌手碌嘀;
(6) 根據(jù)風(fēng)格查詢歌曲。
插入數(shù)據(jù)
(1) 插入歌曲歪架、歌手或組合股冗、專輯、唱片公司和蚪、作詞人止状、作曲人;
(2) 插入歌曲時(shí)攒霹,選擇演唱者怯疤,選擇專輯,選擇作詞人和作曲人催束;
(3) 插入歌手或組合時(shí)集峦,選擇公司;
(4) 插入專輯時(shí)抠刺,選擇演唱者塔淤。
刪除數(shù)據(jù)
(1) 刪除歌曲、歌手或組合速妖、專輯高蜂、唱片公司、作詞人买优、作曲人妨马。
更改數(shù)據(jù)
(1) 更改以下實(shí)體集的屬性:歌曲、歌手或組合杀赢、專輯烘跺、唱片公司、作詞人脂崔、作曲人滤淳;
(2) 更改歌曲的演唱者、作詞人和作曲人及所屬專輯砌左,或改為空脖咐;
(3) 更改歌手或組合所屬的公司,或改為空汇歹;
(4) 更改專輯的演唱者屁擅,或改為空。
(三) 邏輯設(shè)計(jì)
1.模式的合并
上面ER圖中产弹,共包括8個(gè)實(shí)體和10個(gè)聯(lián)系派歌。
(1) 一對(duì)一聯(lián)系有:TitleSong, PerformBand, PerformSinger。
(2) 一對(duì)多聯(lián)系有:AlbumMember, CreateAlbum, WorkOn, LyricsBy, Compose。
(3) 多對(duì)多聯(lián)系有:BandMember胶果,SingSong匾嘱。
需要說(shuō)明的是
(1) 一個(gè)歌手可能存在多個(gè)組合中。這可能是因?yàn)橐恍└枋炙诮M合解散之后早抠,他們加入了另一個(gè)組合霎烙,或者是有一些組合為非商業(yè)性的,允許其成員加入另一個(gè)組合蕊连。因此悬垃,BandMember為多對(duì)多聯(lián)系。
(2) 一首歌曲甘苍,可能由兩人合唱盗忱,但是這兩人由不構(gòu)成一個(gè)組合。因此羊赵,SingSong為多對(duì)多聯(lián)系。
根據(jù)下面的合并規(guī)則
(1) 一對(duì)多的聯(lián)系扇谣,聯(lián)系集可以合并到“一”對(duì)應(yīng)的那個(gè)實(shí)體集的關(guān)系模式中昧捷;
(2) 一對(duì)一的聯(lián)系,聯(lián)系集可以合并到的任何一個(gè)實(shí)體集的關(guān)系模式中罐寨。
因此
(1) 將TitleSong合并到Album中靡挥;
(2) 將PerformBand合并到Band中;
(3) 將PerformSinger合并到Singer中鸯绿;
(4) 將AlbumMember合并到Song中跋破;
(5) 將CreateAlbum合并到Album中;
(6) 將WorkOn合并到Performer中瓶蝴;
(7) 將LyricsBy合并到Song毒返;
(8) 將Compose合并到Song。
2.將ER圖轉(zhuǎn)化為關(guān)系模式
實(shí)體集
- Song(<u>id</u>, name, style, issue_date, duration, lyricist_id, composer_id, album_id)
- Album(<u>id</u>, name, issue_date, title_song_id, performer_id)
- Performer(<u>id</u>, company_id)
- Band(<u>id</u>, name, region, performer_id)
- Singer(<u>id</u>, name, gender, region, performer_id)
- Company(<u>id</u>, name, region, established_time)
- Lyricist(<u>id</u>, name, gender)
- Composer(<u>id</u>,name, gender)
聯(lián)系集
- SingSong(<u>song_id</u>, <u>performer_id</u>)
- BandMember(<u>band_id</u>, <u>singer_id</u>)
注:上述關(guān)系模式中舷手,帶下劃線的屬性為主鍵拧簸,加粗的為非空屬性,斜體的為外鍵男窟。
3.視圖
視圖關(guān)系可以定義為包含查詢結(jié)果的關(guān)系盆赤。視圖是有用的,它可以隱藏不需要的屬性歉眷,可以把信息從多個(gè)關(guān)系收集到一個(gè)單一的視圖中牺六。
下面定義了一些視圖,在“具體實(shí)現(xiàn)”這一節(jié)中汗捡,我們將對(duì)它們進(jìn)行具體的實(shí)現(xiàn)
PerformerName:查詢演唱者的ID和名字(歌手或者組合的名字)淑际。
SongOfPerformer:查詢演唱者演唱的所有歌曲。
AlbumOfPerformer:查詢演唱者創(chuàng)作的所有專輯。
SingerInfor:查詢歌手的詳細(xì)信息庸追,包括所屬的唱片公司霍骄。
BandInfor:查詢組合的詳細(xì)信息,包括所屬的唱片公司淡溯。
SingerOfBand:查詢組合中所有的歌手读整。
SongInfor:查詢歌曲的詳細(xì)信息,包括作詞人和作曲人的名稱以及所屬專輯的名稱咱娶。
SongOfAlbum:查詢專輯中所有的歌曲米间。
AlbumInfor:查詢專輯的詳細(xì)信息,包括創(chuàng)作專輯的表演者和主打歌膘侮。
PerformerOfCompany:查詢公司和旗下的所有表演者屈糊。
4.索引
創(chuàng)建索引的目的
索引(index)是一種數(shù)據(jù)結(jié)構(gòu),它允許數(shù)據(jù)庫(kù)系統(tǒng)高級(jí)地找到關(guān)系中那些在索引屬性上給出定值的元祖琼了,而不用掃描關(guān)系中的所有元祖逻锐。
因此,在下面的關(guān)系模式的屬性上建立索引
- Song.name
- Album.name
- Singer.name
- Band.name
(四) 觸發(fā)器及事務(wù)管理
1.觸發(fā)器
根據(jù)以下定義
觸發(fā)器(trigger)是一條語(yǔ)句雕薪,當(dāng)對(duì)數(shù)據(jù)庫(kù)作修改時(shí)昧诱,它被自動(dòng)執(zhí)行。要設(shè)置觸發(fā)器機(jī)制所袁,必須滿足兩個(gè)要求:
- 指明什么條件下執(zhí)行觸發(fā)器盏档。
- 指明觸發(fā)器執(zhí)行時(shí)的動(dòng)作。
觸發(fā)器有很多適合的用途燥爷,但是在如下場(chǎng)合下蜈亩,不應(yīng)該使用觸發(fā)器。
- 使用觸發(fā)器是替代級(jí)聯(lián)特性來(lái)實(shí)現(xiàn)外鍵約束的on delete cascade特性前翎。因?yàn)檫@樣不僅需要完成大量的工作量稚配,而且會(huì)使數(shù)據(jù)庫(kù)中的約束集合難以理解。
- 使用觸發(fā)器來(lái)維護(hù)視圖鱼填。
- 使用觸發(fā)器來(lái)復(fù)制和備份數(shù)據(jù)庫(kù)药有。
此外,使用觸發(fā)器時(shí)應(yīng)特別小心苹丸,因?yàn)檫\(yùn)行期間一個(gè)觸發(fā)器可以引發(fā)另一個(gè)觸發(fā)器愤惰。在最壞的情況下,一個(gè)觸發(fā)器錯(cuò)誤會(huì)導(dǎo)致一個(gè)無(wú)限的觸發(fā)鏈赘理。
定義如下觸發(fā)器
- InsertPerformer
- 觸發(fā)條件:在插入一個(gè)歌手或者一個(gè)組合之后宦言。
- 動(dòng)作:在Perfromer表中插入一條數(shù)據(jù),然后將相應(yīng)的Performer.id作為這個(gè)歌手或者組合屬性performer_id的值商模。
2.事務(wù)管理
事務(wù)的定義如下[2]
事務(wù)(transaction)是訪問并可能更新各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)行單元奠旺。
事務(wù)具有ACID特性:原子性蜘澜、一致性、隔離性响疚、持久性鄙信。
- 原子性保證事務(wù)的所有映像在數(shù)據(jù)庫(kù)中要么全部反映出來(lái),要么根本不反映忿晕;一個(gè)故障不能讓數(shù)據(jù)庫(kù)處于事務(wù)部分執(zhí)行后的狀態(tài)装诡。
- 一致性保證若數(shù)據(jù)庫(kù)一開始是一致的,則事務(wù)(單獨(dú))執(zhí)行后數(shù)據(jù)庫(kù)仍處于一致狀態(tài)践盼。
- 隔離性保證并發(fā)執(zhí)行的事務(wù)是相互隔離鸦采,使得每個(gè)事務(wù)感覺不到系統(tǒng)中其他的事務(wù)的并發(fā)執(zhí)行。
- 持久性保證一旦一個(gè)事務(wù)提交后咕幻,它對(duì)數(shù)據(jù)庫(kù)的改變不會(huì)丟失渔伯,既是系統(tǒng)可能出現(xiàn)故障。
事務(wù)管理的目的就是肄程,維護(hù)事物的ACID特性锣吼,分為并發(fā)控制和恢復(fù)系統(tǒng)。雖然這些顯得十分復(fù)雜蓝厌,但在界面設(shè)計(jì)那一節(jié)中吐限,我們將看到如何用簡(jiǎn)單的django語(yǔ)句實(shí)現(xiàn)簡(jiǎn)單的事務(wù)管理。
(五) 具體實(shí)現(xiàn)(MySql)
1.建表
以下為創(chuàng)建MySQL數(shù)據(jù)表的SQL通用語(yǔ)法:
CREATE TABLE table_name (column_name column_type);
在上一節(jié)中褂始,一共定義了10張數(shù)據(jù)表能扒。在附錄2中給出了創(chuàng)建它們的sql語(yǔ)句域那。
2.添加視圖
以下為創(chuàng)建視圖的SQL通用語(yǔ)法:
CREATE VIEW view_name AS + [查詢語(yǔ)句];
在上一節(jié)中,一共定義了10個(gè)視圖伞剑。在附錄3中給出了創(chuàng)建它們的sql語(yǔ)句舀寓。
3.添加觸發(fā)器
以下為創(chuàng)建觸發(fā)器的通用語(yǔ)法:
CREATE TRIGGER trigger_name
AFTER/BEFORE
INSERT/UPDATE/DELETE ON table_name
FOR EACH ROW
BEGIN
sql語(yǔ)句
END;
因此胆数,使用如下sql語(yǔ)句創(chuàng)建兩個(gè)觸發(fā)器
create trigger InsertPerformer1
after
insert on Singer
for each row
begin
insert into Performer values();
set new.performer_id = (select max(id) from Performer);
end;
create trigger InsertPerformer2
before
insert on Band
for each row
begin
insert into Performer values();
set new.performer_id = (select max(id) from Performer);
end;
4.添加索引
創(chuàng)建索引的語(yǔ)法相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,如下
CREATE INDEX index_name on table_name(column_name);
因此互墓,使用如下語(yǔ)句創(chuàng)建4個(gè)索引
create index Song_name_index on Song(name);
create index Album_name_index on Album(name);
create index Singer_name_index on Singer(name);
create index Band_name_index on Band(name);
5.導(dǎo)出EER圖
下面的的EER圖(Enhanced Entity-Relationship Model)必尼,是使用MySQL Workbench導(dǎo)出的
(六) 界面設(shè)計(jì)(django)
需要說(shuō)明的是,這一節(jié)的大部分內(nèi)容已經(jīng)超出了實(shí)驗(yàn)的要求篡撵,但是為了以后參考的方便判莉,在這里總結(jié)以下django搭建網(wǎng)站的主要步驟。因此育谬,這部分更像一個(gè)關(guān)于django教程券盅。本次實(shí)驗(yàn)中所有的代碼都可以在https://github.com/1140310118/music_pool處獲取。以下大部分的內(nèi)容膛檀,參考自http://www.kancloud.cn/wizardforcel/django-chinese-docs-18/锰镀。
需要再次強(qiáng)調(diào)的是娘侍,本次實(shí)驗(yàn)使用的django版本是1.8。這是因?yàn)橛韭煌姹镜膁jango之間的存在一定的差異憾筏。
這一節(jié)的目錄如下
- 安裝django
- 創(chuàng)建項(xiàng)目mysite
- 創(chuàng)建應(yīng)用music_pool
- 將數(shù)據(jù)庫(kù)導(dǎo)出到 model.py 中
- 啟用網(wǎng)站管理
- 創(chuàng)建頁(yè)面
- 使用表單
- 簡(jiǎn)單的事務(wù)管理
1. 安裝django
在命令行中使用如下命令安裝django
pip install django==1.8
安裝結(jié)束,在命令行中輸入python花鹅。然后嘗試導(dǎo)入django
>>> import django
>>> django.get_version()
'1.8'
如果你使用的是Python3氧腰,那么安裝后可能存在關(guān)于數(shù)據(jù)庫(kù)的問題。
django 使用的MySQLdb連接數(shù)據(jù)庫(kù)翠胰,但是MySQLdb只支持Python2.容贝,還不支持python3。
因此之景,我們使用PyMySQL代替MySQLdb斤富。具體來(lái)說(shuō),在下面的文件中
[Python的路徑]\Lib\site-packages\django\db\backends\mysql\__init__.py
添加如下語(yǔ)句
import pymysql
pymysql.install_as_MySQLdb()
2. 創(chuàng)建項(xiàng)目mysite
在命令行中锻狗,使用cd命令進(jìn)入存儲(chǔ)你想存儲(chǔ)代碼的目錄满力,然后運(yùn)行以下命令
django-admin.py startproject mysite
于是,當(dāng)前目錄下建立了一個(gè)mysite目錄轻纪,結(jié)構(gòu)如下
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
從外層的mysite目錄切換進(jìn)去油额,通過(guò)如下命令,我們就能運(yùn)行服務(wù)器
python manage.py runserver
在http://127.0.0.1:8000/刻帚,我們將看到如下頁(yè)面
3. 編輯setting.py
在mysite/settings.py中保存Django項(xiàng)目的配置×仕唬現(xiàn)在通過(guò)編輯它,修改項(xiàng)目的配置崇众。
修改數(shù)據(jù)庫(kù)設(shè)置(DATABASES)為
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'music_pool',
'USER': 'root',
'HOST': '',
'PORT': '3306',
'PASSWORD':[你的密碼],
}
}
修改完成之后掂僵,運(yùn)行如下命令,進(jìn)行數(shù)據(jù)庫(kù)的同步
python manage.py syncdb
運(yùn)行此命令后顷歌,命令行會(huì)提示是否創(chuàng)建管理員賬戶锰蓬,選擇是,因?yàn)檫@將會(huì)非常有用眯漩。
設(shè)置語(yǔ)言版本
LANGUAGE_CODE = 'zh-cn'
注:在1.9及以后的版本中芹扭,需要使用'zh-hans'。
更改時(shí)區(qū)(TIME_ZONE)
TIME_ZONE = 'Asia/Shanghai'
4. 創(chuàng)建應(yīng)用music_pool
使用如下命令赦抖,創(chuàng)建應(yīng)用
python manage.py startapp music_pool
這將創(chuàng)建一個(gè)music_pool目錄舱卡,如下
music_pool/
__init__.py
models.py
tests.py
views.py
為了激活這個(gè)應(yīng)用,我們編輯setting.py文件队萤,在INSTALLED_APPS設(shè)置中加入'music_pool'灼狰,結(jié)果如下
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'music_pool',
)
5. 將數(shù)據(jù)庫(kù)導(dǎo)出到 models.py 中
在music_pool/models.py中,我們可以創(chuàng)建按照如下的方式浮禾,創(chuàng)建模型
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=255)
region = models.CharField(max_length=255)
established_time = models.DateTimeField('date established')
class Performer(models.Model):
company = models.ForeignKey(Company)
#...
然后在命令行中使用如下命令交胚,在數(shù)據(jù)庫(kù)中創(chuàng)建相應(yīng)的表
python manage.py syncdb
但是份汗,由于我們已經(jīng)在數(shù)據(jù)庫(kù)中創(chuàng)建了表,因此采取導(dǎo)入MySQL數(shù)據(jù)庫(kù)的辦法蝴簇。在命令行中杯活,使用如下語(yǔ)句
python manage.py inspectdb >music_pool/models.py
這樣,MySQL數(shù)據(jù)庫(kù)中的表就導(dǎo)出到models.py中熬词。比如在models.py建立了一個(gè)Album對(duì)象與數(shù)據(jù)庫(kù)中的Album表相對(duì)應(yīng)
class Album(models.Model):
name = models.CharField(max_length=255)
issue_date = models.DateField(blank=True, null=True)
title_song = models.ForeignKey('Song', blank=True, null=True)
performer = models.ForeignKey('Performer', blank=True, null=True)
class Meta:
managed = False
db_table = 'album'
manage.py = False
表明告訴Django不要管理此表的創(chuàng)建旁钧、修改和刪除。為了預(yù)防一些潛在的錯(cuò)誤互拾,建議注釋掉這一行歪今。這里需要注意的是
當(dāng)Django根據(jù)models.py中的模型創(chuàng)建數(shù)據(jù)庫(kù)中的表時(shí),會(huì)在未指明主鍵的情況下為每個(gè)模型分配一個(gè)id作為主鍵颜矿;每個(gè)模型中的外鍵屬性寄猩,在表中的名字會(huì)被附上"_id"。
因此骑疆,相應(yīng)地田篇,從數(shù)據(jù)庫(kù)中導(dǎo)數(shù)的models中的對(duì)象
- 不會(huì)有id屬性;
- 外鍵屬性中的"_id"也會(huì)被去掉箍铭。
因此泊柬,導(dǎo)出之后會(huì)存在一些錯(cuò)誤。如在Bandmember中
unique_together = (('band_id', 'singer_id'),)
我們改成
unique_together = (('band', 'singer'),)
這里的unique_together是為了解決django不支持多字段主鍵的問題诈火。
此外兽赁,在啟動(dòng)服務(wù)器還出現(xiàn)如下錯(cuò)誤
HINT: Rename field 'Song.album', or add/change a related_name argument to the definition for field 'Album.title_song'.
因此,類Album進(jìn)行相應(yīng)的修改
title_song = models.ForeignKey('Song', blank=True, null=True, related_name='title_song')
修改完畢之后冷守,再次運(yùn)行 python manage.py syncdb
以同步據(jù)庫(kù)闸氮。
6. 啟用網(wǎng)站管理
Django 是在新聞編輯室環(huán)境下編寫的,“內(nèi)容發(fā)表者”和“公共”網(wǎng)站之間有 非常明顯的界線教沾。網(wǎng)站管理員使用這個(gè)系統(tǒng)來(lái)添加新聞、事件译断、體育成績(jī)等等授翻, 而這些內(nèi)容會(huì)在公共網(wǎng)站上顯示出來(lái)。Django 解決了為網(wǎng)站管理員創(chuàng)建統(tǒng)一 的管理界面用以編輯內(nèi)容的問題孙咪。
管理界面不是讓網(wǎng)站訪問者使用的堪唐。它是為網(wǎng)站管理員準(zhǔn)備的。
使用如下命令翎蹈,啟動(dòng)服務(wù)器
python manage.py runserver
使用瀏覽器淮菠,訪問http://127.0.0.1:8000/admin/。我們將看到如下的登錄界面
輸入在前面創(chuàng)建的用戶名和密碼荤堪,登錄進(jìn)去合陵。我們將看到
這些是一些可編輯的內(nèi)容枢赔,包括group,users 和 sites拥知。這些都是django默認(rèn)情況下自帶的核心功能踏拜。
下面,我們 Song 對(duì)象添加到這個(gè)頁(yè)面低剔。首先找到music_pool/admin.py速梗,如果沒有,那就創(chuàng)建一個(gè)襟齿。
music_pool/
__init__.py
models.py
tests.py
views.py
admin.py
在admin.py文件中添加如下內(nèi)容:
from django.contrib import admin
from music_pool.models import Song
admin.site.register(Song)
重啟服務(wù)器姻锁,登錄管理員賬戶,我們將看到如下頁(yè)面
然后猜欺,我們就可以對(duì)Song對(duì)象進(jìn)行編輯了位隶!比如添加一條記錄。
7. 創(chuàng)建頁(yè)面
在這一步將創(chuàng)建一個(gè)頁(yè)面替梨,用來(lái)顯示所有的歌曲及其作詞人钓试、作曲人和所屬專輯。
在music_pool目錄下創(chuàng)建一個(gè)名為url.py的文件副瀑。
music_pool/
__init__.py
admin.py
models.py
tests.py
urls.py
views.py
在music_pool/url.py文件中添加以下內(nèi)容
from django.conf.urls import patterns, url
from music_pool import views
urlpatterns = patterns('',
url(r'^$', views.all_song, name='songs')
)
接下來(lái)弓熏,在mysite/urls.py中添加一個(gè)include()方法,于是這個(gè)文件內(nèi)容變成下面的樣子
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^music_pool/', include('music_pool.urls')),
url(r'^admin/', include(admin.site.urls)),
)
URL部分的任務(wù)完成了糠睡,接下來(lái)挽鞠,我們需要編寫URL對(duì)應(yīng)的views.all_song這個(gè)方法了。
在music_pool/views.py文件中添加如下語(yǔ)句
from django.shortcuts import render
from music.models import Song
def all_song(request):
song_list=Song.get_all()
context = {'song_list': song_list}
return render(request, 'music_pool/song_list.html', context)
在函數(shù)views.all_song狈孔,我們首先通過(guò)models.Song查詢得到了所有的歌曲信认,然后將參數(shù)傳遞給模板music/song_list.html。
首先均抽,我們來(lái)實(shí)現(xiàn)Song.get_all()這個(gè)函數(shù)嫁赏,編輯music_pool/models.py,在Song這個(gè)類下添加如下方法
@classmethod
def get_all(self):
sql=""" select name, style, issue_date, duration, lyricist_name, composer_name, album_name
from `SongInfor`
"""
song_list=Song.objects.raw(sql)
return song_list
接下來(lái)油挥,我們添加模板music_pool/song_list.html潦蝇。在music_pool下創(chuàng)建一個(gè)templates目錄,在這個(gè)目錄下創(chuàng)建一個(gè)music_pool目錄深寥,并在其中創(chuàng)建一個(gè)song_list.html文件攘乒。于是,我們的模板文件的路徑應(yīng)該是mysite/music_pool/templates/music_pool/song_list.html惋鹅。
在song_list.html添加如下內(nèi)容
{% if song_list %}
<ul>
{% for song in song_list %}
{{song.name}}
{{song.style}}
{{song.issue_date}}
{{song.duration}}
{{song.lyricist_name}}
{{song.composer_name}}
{{song.album_name}}
{% endfor %}
</ul>
{% else %}
<p>No Song are available.</p>
{% endif %}
8. 使用表單
略
9. 簡(jiǎn)單的事務(wù)管理
下面實(shí)現(xiàn)了事務(wù)的原子性则酝。
from django.db import transaction
@transaction.atomic
def view_func(request):
try:
with transaction.atomic():
# ...
except IntegrityError:
# ...
在比1.8更高的版本中,提供了更加高級(jí)的事務(wù)管理接口闰集。
四沽讹、實(shí)驗(yàn)體會(huì)
- 本次實(shí)驗(yàn)的主要任務(wù)是數(shù)據(jù)庫(kù)設(shè)計(jì)般卑,過(guò)分地將精力放在django上,實(shí)在不好妥泉,不好椭微。
附錄1 數(shù)據(jù)庫(kù)設(shè)計(jì)階段
- 刻畫用戶需求
- 概念設(shè)計(jì)
- 構(gòu)建ER圖:實(shí)體、實(shí)體的屬性盲链、實(shí)體之間的聯(lián)系蝇率、實(shí)體和聯(lián)系上的約束
- 明確功能需求:描述在數(shù)據(jù)上進(jìn)行的各類操作
- 邏輯設(shè)計(jì)
- 將高層概念模式映射到將使用的數(shù)據(jù)庫(kù)系統(tǒng)的實(shí)現(xiàn)數(shù)據(jù)模型上,通常是將ER模型映射到關(guān)系模式刽沾。
- 物理設(shè)計(jì)
- 指明數(shù)據(jù)庫(kù)的物理特征本慕,包括文件組織格式和索引結(jié)構(gòu)的選擇。
附錄2 MySQL-創(chuàng)建數(shù)據(jù)表
Create table Song(`id` int(8) not null auto_increment,
name varchar(255) not null,
style varchar(255),
issue_date date,
duration time,
lyricist_id int(8),
composer_id int(8),
album_id int (8),
primary key(`id`));
Create table Album(`id` int(8) not null auto_increment,
name varchar(255) not null,
issue_date date,
title_song_id int(8),
performer_id int(8),
primary key(`id`));
Create table Performer(`id` int(8) not null auto_increment,
company_id int(8),
primary key(`id`));
Create table Band(`id` int(8) not null auto_increment,
name varchar(255) not null,
region varchar(255),
performer_id int(8),
primary key(`id`));
Create table Singer(`id` int(8) not null auto_increment,
name varchar(255) not null,
gender varchar(255),
region varchar(255),
performer_id int(8),
primary key(`id`));
Create table Company(`id` int(8) not null auto_increment,
name varchar(255) not null,
region varchar(255),
established_time date,
primary key(`id`));
Create table Lyricist(`id` int(8) not null auto_increment,
name varchar(255) not null,
gender varchar(255),
primary key(`id`));
Create table Composer(`id` int(8) not null auto_increment,
name varchar(255) not null,
gender varchar(255),
primary key(`id`));
Create table SingSong(song_id int(8) not null,
performer_id int(8) not null,
primary key(song_id,performer_id));
Create table BandMember(band_id int(8) not null,
singer_id int(8) not null,
primary key(band_id,singer_id));
添加外鍵約束
alter table Song
add constraint lyricsBy foreign key (lyricist_id)
references Lyricist (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Song
add constraint Compose foreign key (composer_id)
references Composer (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Song
add constraint album_member foreign key (album_id)
references Album (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Album
add constraint title_song foreign key (title_song_id)
references Song (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Album
add constraint create_album foreign key (performer_id)
references Performer (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Performer
add constraint work_on foreign key (company_id)
references Company (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Band
add constraint performer_band foreign key (performer_id)
references Performer (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table Singer
add constraint performer_Singer foreign key (performer_id)
references Performer (`id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
alter table SingSong
add constraint sing_song foreign key (song_id)
references Song (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
alter table SingSong
add constraint song_performer foreign key (performer_id)
references Performer (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
alter table BandMember
add constraint bandmember_band foreign key (band_id)
references Band (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
alter table BandMember
add constraint bandmember_singer foreign key (singer_id)
references Singer (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
附錄3 MySQL-創(chuàng)建視圖
create view PerformerName as
select Performer.id as id, Band.name as band_name, Singer.name as singer_name
from Performer left outer join Band on (Performer.id=Band.performer_id)
left outer join Singer on (Performer.id=Singer.performer_id);
create view SongOfPerformer as
select SingSong.performer_id, SingSong.song_id, Song.name
from SingSong join Song on (SingSong.song_id=Song.id);
create view AlbumOfPerformer as
select performer_id, id as album_id, name as album_name
from Album;
create view SingerInfor as
select Singer.id, Singer.name, Singer.gender, Singer.region, Singer.performer_id, Company.name as company_name, Company.id as company_id
from Singer join Performer on (Singer.performer_id=Performer.id)
left join Company on (Performer.company_id=Company.id);
create view BandInfor as
select Band.id, Band.name, Band.region, Band.performer_id, Company.name as company_name, Company.id as company_id
from Band join Performer on (Band.performer_id=Performer.id)
left join Company on (Performer.company_id=Company.id);
create view SingerOfBand as
select BandMember.band_id, Singer.performer_id as singer_performer_id, Singer.name as singer_name
from BandMember join Band on (Band.id=BandMember.band_id)
join Singer on (Singer.id=BandMember.singer_id);
create view SongInfor as
select Song.id, Song.name, Song.style, Song.issue_date, Song.duration,
lyricist_id, Lyricist.name as lyricist_name,
composer_id, Composer.name as composer_name,
album_id, Album.name as album_name
from Song left outer join Album on (Song.album_id=Album.id)
left outer join Composer on (Song.composer_id=Composer.id)
left outer join Lyricist on (Song.lyricist_id=Lyricist.id);
create view SongOfAlbum as
select Song.id as song_id, Song.name as song_name, Song.album_id
from Song;
create view AlbumInfor as
select Album.id, Album.name, Album.issue_date, title_song_id, performer_id, Song.name as title_song_name
from Album join Song on (Album.title_song_id=Song.id);
create view PerformerOfCompany as
select Company.id as company_id, Company.name as company_name, Performer.id as performer_id
from Company join Performer on (Company.id=Performer.company_id);
參考文獻(xiàn)
-
CSDN博客——(七)數(shù)據(jù)庫(kù)ER圖(二) 2017/5/25 http://blog.sina.com.cn/s/blog_68163d080100j6m6.html ?
-
數(shù)據(jù)庫(kù)系統(tǒng)概念 第6版侧漓。 ?