設計你的資料庫系統(三)

by adonisy 30. 九月 2017 14:06

    者:楊先民 
    稿:張智凱 


1 前言

上期大概把「油耗維修」這隻程式的一些需要用到的圖片以及工具稍微介紹了一下,本期將要進入資料庫系統的重點,也就是資料庫設計篇了。

2 設計資料庫

我設計資料庫的時後,因為只有一台車的油耗以及保修資訊要記錄,所以就想很單純的把資料庫設計在一個 sqlite資料庫中,我命名為 OilInfo.sqlite,之後有加入多台車的概念是之後的事了,這個牽涉到使用者需求的修改問題,所以台灣的專案資料庫常常搞的一團亂,最主要的因素還是在使用者需求改來改去的關係。


資料庫設計一直有兩套的設計方法論,若是把使用者需求拆成「實體」與「屬性」的話,有些人是先找出所有的實體,有些人則是先把所有的屬性找出來,學校的教法通常是先找出所有的屬性,因為如果你之前沒有設計過類似資料庫的話,很難複製相同的經驗。


而我所撰寫的「實戰資料庫設計」中,很多時後是使用尋找實體再找屬性的方式來設計資料庫的。

而這次我們採用的資料庫設計,是使用先找實體,再抓屬性的方式完成。

首先,我們要記錄車子的油耗,所以一定會有車籍的資訊,所以我們有一個資料表叫做「car」,裡面定義了車子的相關資訊。

想想看,你會存入什麼資訊到車子裡面?首先我定義了carid,車輛編號,因為設計資料庫的習慣就是會設計一個主索引鍵,而這個主索引鍵並不會重覆。當然,這樣的設計也埋下了之後有多輛車的伏筆存在。

接下來,會有NickName,也就是暱稱這樣的屬性,你需要為你的愛車命個名稱以供識別。所以我們的車都會有一個名字,而且是你自己取的,感覺有點親切不是嗎?

和這輛車子相關,想要記錄下來的資訊有哪些呢?

我加入了車廠carCompany、車型 carStyle還有愛車生日carBirthday、顏色carColor以及車的照片carimg欄位(事實上事後寫程式才發現其實車的照片欄位並不需要被設計,原因之後會說明)

這些屬性都是和車子的資料有完全相關,所以不用擔心會沒有正規化的問題,你總不可能把這些屬性拿到其他的資料表吧,它們絕對和carid有相依性的。

目前的問題在,車廠與車型的資料,是要記錄真正的車廠名稱,還是記錄車廠編號這種東西呢?

會有這樣的疑問是,車廠我們假設有 BMW、Benz、Nissan這三家,如果只記錄車廠代號的話,代表車主無法自行輸入別的可能存在的其他家車廠資料,但是各位應該知道,你是無法搜集到全世界的車廠車型資料的,必要的時後,車主需要自行輸入我沒有列出的車廠車型資料,例如一些大陸生產的車輛,所以這裡我是採用車廠名稱與車型名稱,而不使用代號的方式,讓車主可以利用選單選擇屬於自己的車廠與車型,但是如果沒有列出來的話,則是自行輸入,也就是如下圖的畫面:

可以兼顧使用者選擇車廠,找尋屬於自己車子車型的快樂(?),如果找不到也沒有關係,可以自行輸入屬於自己愛車的車廠與車型資料。

附帶一提,這個車廠與車型資料表,我設計在另一個資料庫,叫做 carSetting.sqlite,因為我會隨時更新最新車廠與車型的資料,車主可以利用下載的方式取得最新車廠車型資訊,也就是下圖的功能:

最新車廠名單下載,可以讓車主下載最新的車廠資訊,還會記錄最新的更新日期讓車主判斷自己的資料庫是不是太過時了。

大家可能以為這個功能沒什麼重要,其實車主很在乎這些小東西的,之前上架後,就有很多車主還寫信問我,他找不到他車子的車廠資訊,問我可不可以加上去之類的。

所以後來設計一個功能讓車主可以自行輸入沒在列表中的車廠車型資料。

不過話說回來,車廠車型我是希望大家儘量是用選單選擇自己車的車廠車型,原因很簡單,因為我有做一個功能,就是上傳油耗資訊並且進行比對,如果自己輸入的車廠車型太過於特殊的話,可能就沒有人可以跟你比較了,我還曾看過上傳的資料有「蓋美麗」或是「仙草」這種車型,其實就是 Camry與 Sentra,我不明白為什麼要有車主要自創這樣的型號?

而且大家要注意,使用者界面的方便輸入,也是讓整體應用程式效能調校提升的方式之一,很多人常抱怨設計的應用程式效能不好,仔細想想你的使用者界面有思考過該如何設計嗎?一個良善、好輸入的使用者界面,也是提升效能的方式。

其實在設計資料庫之時,心中就要浮現應用程式會用什麼方式呈現,也就是上圖的內容,因為你想要如何呈現資料,就會間接知道資料庫該如何設計,在我所著的「實戰資料庫設計」一書中,我是利用一些假資料來達到這樣的目的,但是如果你本身會寫程式,利用程式設計的 UI界面預想,也是一個很好的辦法。

原本只想記錄一台車的油耗資訊,所以只設計一台車規格的資料庫,但是後來為了區分 free版以及 pro版,pro版可以支援 N台車油耗的建立(N為任意數),所以這時又要思考該如何修改原先的資料庫結構。

原本車主的車𨋣,是記錄在 car這個資料表上,利用 carid來區分資料不重複,理想的做法就是新增一台新車時,放在同一個資料表中,給它多一個 carid這樣就好。

但是當初設計的時後,還是用一個獨立的資料庫OilInfoCar1.sqlite來存放第二台車以後的資料。

換句話說,原本的 OilInfo.sqlite資料庫中的 car資料表,裡面只有一筆資料列,而第二台以後的車,則都是放在 OilInfoCar1.sqlite的 car資料表中。

現在回想,這樣的設計有利有弊,因為當時要區分 free版以及 pro版的功能,所以用第二個資料庫來儲存第二台車以後的資料,但是缺點就是資料庫就會變多,以後車主要異動資料時要用假設句去判斷要修改哪個資料庫,比較麻煩,不過 app上架已經多時,現在想要再修改資料庫結構也為時以晚了,所以設計資料庫時的使用者需求時常變動會造成本例的問題。

目前設計的資料庫以及資料表如下:

OilInfo.sqlite:

資料表

car(carid,carNickName,carCompany,carStyle,carColor,carimg,cartype)

OilInfoCar1.sqlite

資料表

car(carid,carNickName,carCompany,carStyle,carColor,carimg,cartype)

carSetting.sqlite
資料表

carCompany(companyID,carCompany,carCompanyEng,updatedate)

carCompany_moto(companyID,carCompany,carCompanyEng,updatedate)

carStyle(styleid,styleName,styleNameEng,companyID,updatedate)

carStyle_moto(styleid,styleName,styleNameEng,companyID,updatedate)

下期繼續介紹資料庫設計的過程。

Tags:

SQLite

不允許評論

NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List