安卓学习日志 Day15 — 数据库基础
文章目錄
- 概述
- 數(shù)據(jù)持久性
- 不同的存儲(chǔ)類(lèi)型選擇
- 現(xiàn)實(shí)生活中的數(shù)據(jù)庫(kù)
- SQLite 數(shù)據(jù)庫(kù)
- 安裝 SQLite
- 第一次打開(kāi) SQLite
- SQLite 中的類(lèi)型
- 設(shè)計(jì)和創(chuàng)建數(shù)據(jù)庫(kù)
- 快速提示
- CRUD
- CURD 概述
- 插入 INSERT
- 表格的局限
- 選擇、位置和排序
- 更新 UPDATE
- 刪除 DELETE
- 總結(jié)
- 參考
概述
目前為止,已經(jīng)構(gòu)建了各個(gè)不同的應(yīng)用,也可能正急于構(gòu)建自己的應(yīng)用,但或許沒(méi)有具體的想法。一個(gè)很好的練習(xí)方法是詢(xún)問(wèn)下當(dāng)?shù)氐男∩痰昊蚍怯麢C(jī)構(gòu),看看他們是否需要幫助構(gòu)建一個(gè) Android 應(yīng)用。
周?chē)泻芏嗟男∩痰甓夹枰蛴脩籼峁┬畔?#xff0c;例如餐廳里的菜單、干洗店和裁縫店需要列出可以提供的服務(wù)。
還有更多類(lèi)似的例子,需要將這些數(shù)據(jù)存儲(chǔ)到某個(gè)地方,例如應(yīng)用中 以便隨時(shí)隨地地訪問(wèn)這些數(shù)據(jù)。用戶可以使用這一應(yīng)用,店內(nèi)人員也可以使用這一應(yīng)用來(lái)管理日常事物或跟蹤庫(kù)存情況。
之后將研究一個(gè)示例,為一個(gè)收容所的工作人員開(kāi)發(fā)一款移動(dòng)應(yīng)用,幫助他們記錄各種不同的寵物。學(xué)習(xí)一個(gè)構(gòu)建數(shù)據(jù)的強(qiáng)大方式,構(gòu)建一款應(yīng)用來(lái)利用這一結(jié)構(gòu),從而允許用戶(店內(nèi)工作人員)輕松獲取每個(gè)寵物的信息,并能夠?qū)@些信息執(zhí)行操作。
數(shù)據(jù)持久性
數(shù)據(jù)持久性,簡(jiǎn)單地說(shuō)就是將數(shù)據(jù)永久的存儲(chǔ)起來(lái),而實(shí)現(xiàn)持久化。
在之前的應(yīng)用中,數(shù)據(jù)均保存在變量當(dāng)中,而變量定義在 Activity 的內(nèi)部,這就意味著變量 與 Activity 的生命周期相同,假如在應(yīng)用運(yùn)行的過(guò)程中用戶動(dòng)態(tài)的改變了變量的值,這時(shí),每當(dāng) Activity 重新加載一次,內(nèi)部的變量就會(huì)重新創(chuàng)建一次(變量的值就會(huì)變?yōu)槟J(rèn)值,而非用戶動(dòng)態(tài)更改的值),這是因?yàn)闆](méi)有數(shù)據(jù)持久化。
對(duì)于即將要構(gòu)建的 寵物應(yīng)用也是如此,如果我們沒(méi)有合理地存儲(chǔ)輸入到應(yīng)用中的寵物信息,一旦 Activity 不再運(yùn)行 這些信息就會(huì)丟失。
不同的存儲(chǔ)類(lèi)型選擇
Android 使用的文件系統(tǒng)類(lèi)似于其他平臺(tái)上基于磁盤(pán)的文件系統(tǒng)。該系統(tǒng)為您提供了以下幾種保存應(yīng)用數(shù)據(jù)的選項(xiàng):
- 應(yīng)用專(zhuān)屬存儲(chǔ)空間:存儲(chǔ)僅供應(yīng)用使用的文件,可以存儲(chǔ)到內(nèi)部存儲(chǔ)卷中的專(zhuān)屬目錄或外部存儲(chǔ)空間中的其他專(zhuān)屬目錄。使用內(nèi)部存儲(chǔ)空間中的目錄保存其他應(yīng)用不應(yīng)訪問(wèn)的敏感信息。
- 共享存儲(chǔ):存儲(chǔ)您的應(yīng)用打算與其他應(yīng)用共享的文件,包括媒體、文檔和其他文件。
- 偏好設(shè)置:以鍵值對(duì)形式存儲(chǔ)私有原始數(shù)據(jù)。
- 數(shù)據(jù)庫(kù):使用 Room 持久性庫(kù)將結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)在專(zhuān)用數(shù)據(jù)庫(kù)中。
可以看出 Android 應(yīng)用中的文件存儲(chǔ)方式主要分為三類(lèi):文件存儲(chǔ)(應(yīng)用專(zhuān)屬存儲(chǔ)空間或共享存儲(chǔ))、偏好設(shè)置(SharedPreferences)、數(shù)據(jù)庫(kù)(Room、SQLite)。
下面有四種應(yīng)用場(chǎng)景:
“Video Everywhere”應(yīng)用可以讓你在度假的時(shí)候拍攝短片,并自動(dòng)根據(jù)你去過(guò)的地點(diǎn)和拍攝短片的日期繪制一張地圖。你該如何存儲(chǔ)這些短片呢?
**答案:**文件存儲(chǔ)
“Baking Conversion”應(yīng)用可以對(duì)烘焙中遇到的各種單位進(jìn)行轉(zhuǎn)換,例如杯數(shù)轉(zhuǎn)換成毫升,湯匙數(shù)轉(zhuǎn)換為杯數(shù)。你該如何存儲(chǔ)用戶的單位偏好設(shè)置?
**答案:**偏好設(shè)置
“Music Share”應(yīng)用可以使你購(gòu)買(mǎi)和下載歌曲用于任何應(yīng)用。你該如何存儲(chǔ)這些歌曲?
**答案:**文件存儲(chǔ)
假設(shè)有一款應(yīng)用可以存儲(chǔ)進(jìn)入收容所的寵物信息。你會(huì)使用什么來(lái)存儲(chǔ)寵物信息?
**答案:**數(shù)據(jù)庫(kù)
還有一種情況,應(yīng)用會(huì)同時(shí)使用不止一種的數(shù)據(jù)持久化方式。
現(xiàn)實(shí)生活中的數(shù)據(jù)庫(kù)
到目前為止,已經(jīng)見(jiàn)過(guò)兩個(gè)在現(xiàn)實(shí)生活中用到數(shù)據(jù)庫(kù)的示例:寵物收容所會(huì)存儲(chǔ)關(guān)于動(dòng)物的數(shù)據(jù),以及在線零售商會(huì)存儲(chǔ)關(guān)于庫(kù)存的數(shù)據(jù)。
日程生活中,有各種需要采用數(shù)據(jù)庫(kù)結(jié)構(gòu)來(lái)存儲(chǔ)信息的示例。下面再舉兩個(gè)例子。
銀行賬戶
銀行不僅非常依賴(lài)于關(guān)于用戶的信息,還需要收集關(guān)于全球市場(chǎng)的信息,這樣才能立足市場(chǎng)。可以想象出他們的數(shù)據(jù)庫(kù)需要使用多個(gè)表格來(lái)匯總相關(guān)數(shù)據(jù)。
例如,他們會(huì)使用一個(gè)表格來(lái)記錄單個(gè)用戶的信息,例如用戶 ID、支票賬號(hào)、支票賬戶金額、儲(chǔ)蓄賬號(hào)、儲(chǔ)蓄賬戶金額、用戶的地址、用戶的生日、用戶名、密碼等。還可能會(huì)使用另一個(gè)表格來(lái)記錄更加通用的信息,例如貨幣匯率、信用卡利率、貸款利率等。
這些數(shù)據(jù)庫(kù)中的信息都需要接受?chē)?yán)密的監(jiān)督,因?yàn)檫@些信息太重要了。聽(tīng)過(guò)“網(wǎng)絡(luò)安全”一詞嗎?組織機(jī)構(gòu)會(huì)專(zhuān)門(mén)設(shè)立一個(gè)部門(mén)來(lái)確保這些數(shù)據(jù)庫(kù)的信息安全性。
航空公司
如果你在航空公司網(wǎng)站上預(yù)訂過(guò)機(jī)票,經(jīng)常就會(huì)需要輸入飛行常客號(hào)碼。航空公司可以利用該數(shù)據(jù)在存儲(chǔ)客戶信息的數(shù)據(jù)庫(kù)表格中進(jìn)行搜索,查找關(guān)于客戶的其他信息。
該表格可能包含其他客戶信息,例如姓名、地址、電話號(hào)碼、飛行常客號(hào)碼、信用卡信息、航班號(hào)碼、座位號(hào)碼等。
此外,航空公司需要表格來(lái)存儲(chǔ)關(guān)于每日航班的信息。這些表格可能包含以下數(shù)據(jù):飛機(jī)號(hào)、起飛機(jī)場(chǎng)、抵達(dá)機(jī)場(chǎng)、已售座位數(shù)、起飛時(shí)間、抵達(dá)時(shí)間、中轉(zhuǎn)航班等。
航空公司會(huì)使用多個(gè)不同表格里的信息來(lái)幫助你選出抵達(dá)目的地最安全高效的方式。
SQLite 數(shù)據(jù)庫(kù)
SQLite 是 Android 自帶的數(shù)據(jù)庫(kù),不需要下載或安裝任何內(nèi)容就能在 Android 應(yīng)用中使用 SQLite,雖然手機(jī)已經(jīng)具有了 SQLite,但是計(jì)算機(jī)并沒(méi)有預(yù)裝 SQLite。
安裝 SQLite
Windwos
Windows 系統(tǒng)中沒(méi)有預(yù)裝 SQLite 數(shù)據(jù)庫(kù)系統(tǒng),需要自行安裝。
詳細(xì)了解下這幾個(gè)步驟。
要下載正確的文件,你需要轉(zhuǎn)到此處并下載下面這兩個(gè)文件:
sqlite-shell-win32-*.zip 和 sqlite-dll-win32-*.zip
將這兩個(gè)文件下載到計(jì)算機(jī)上后,打開(kāi) Windows 資源管理器并轉(zhuǎn)到 C 盤(pán),然后創(chuàng)建一個(gè)文件夾,叫做“sqlite”。將下載的 .zip 文件復(fù)制到該文件夾里,然后解壓縮了。
完成上述操作后,你需要將 C:>sqlite 添加到系統(tǒng)的 PATH 環(huán)境變量里。如果你從未執(zhí)行過(guò)這一操作,請(qǐng)按照這些步驟來(lái)操作。
最后,需要打開(kāi)命令提示符程序,并輸入 sqlite3,然后按下 Enter 鍵。
Mac OS X
最新版本的 OS X 已經(jīng)預(yù)裝了 SQLite,所以可能不需要執(zhí)行任何操作。要查看是否預(yù)裝了 SQLite,打開(kāi)終端程序(可以從桌面的右上角找到該程序),輸入 sqlite3,然后按下 Enter 鍵。如果出現(xiàn)的結(jié)果中包含“SQLite 版本”和一些數(shù)字,那就很幸運(yùn),預(yù)裝了!
如果沒(méi)有,則需要自己手動(dòng)安裝。為此,你需要下載相關(guān)文件,在終端程序中輸入一些命令。
首先轉(zhuǎn)到 此處 并下載 sqlite-autoconf-*.tar.gz。
然后打開(kāi)終端,并輸入以下命令。注意 $ 符號(hào)表示一行的開(kāi)頭位置,不需要輸入。例如,對(duì)于最后一行,只需要輸入“make install”,然后按下 Enter 鍵。
$tar xvfz sqlite-autoconf-3071502.tar.gz$cd sqlite-autoconf-3071502$./configure --prefix=/usr/local$make$make install輸入這些命令后,Mac 上就安裝好 SQLite 了!
第一次打開(kāi) SQLite
sqlite3 在命令提示符窗口里打開(kāi) sqlite3 程序的命令。
sqlite3 shelter.db 打開(kāi) sqlite3 程序并直接打開(kāi)以下數(shù)據(jù)庫(kù)文件的命令。可以將 shelter.db 替換為任何現(xiàn)有的數(shù)據(jù)庫(kù)文件。
.open shelter.db sqlite 在程序中用來(lái)打開(kāi)數(shù)據(jù)庫(kù)文件的命令。在這里,打開(kāi)的是 shelter.db 文件。可以將 shelter.db 替換為任何現(xiàn)有的其他 .db 文件。
.help 調(diào)出可用命令列表的命令
.quit 退出 sqlite 應(yīng)用的命令
Windows 系統(tǒng)
echo %cd% echo 請(qǐng)求計(jì)算機(jī)向屏幕上輸出內(nèi)容。在這里,使用 %cd% 來(lái)要求計(jì)算機(jī)輸出“當(dāng)前目錄”(即當(dāng)前所處的目錄)。
Mac 或 Linux系統(tǒng)
pwd 這一簡(jiǎn)寫(xiě)表示的是“當(dāng)前工作目錄”。和上述 Windows 命令一樣,在屏幕上輸出我們當(dāng)前工作所處的目錄。
sqlite3 在終端里打開(kāi) sqlite3 程序的命令。
SQLite 中的類(lèi)型
大多數(shù) SQL數(shù)據(jù)庫(kù)引擎(據(jù)我們所知,除了SQLite之外的所有SQL數(shù)據(jù)庫(kù)引擎)使用靜態(tài)的、嚴(yán)格的類(lèi)型。使用靜態(tài)類(lèi)型時(shí),值的數(shù)據(jù)類(lèi)型由其容器決定——存儲(chǔ)值的特定列。SQLite 使用更通用的動(dòng)態(tài)類(lèi)型系統(tǒng)。在SQLite中,值的數(shù)據(jù)類(lèi)型與值本身相關(guān)聯(lián),而不是與它的容器相關(guān)聯(lián)。SQLite的動(dòng)態(tài)類(lèi)型系統(tǒng)向后兼容其他數(shù)據(jù)庫(kù)引擎更常見(jiàn)的靜態(tài)類(lèi)型系統(tǒng),因?yàn)樵陟o態(tài)類(lèi)型數(shù)據(jù)庫(kù)上工作的SQL語(yǔ)句在SQLite中應(yīng)該以同樣的方式工作。然而,SQLite中的動(dòng)態(tài)類(lèi)型允許它做一些在傳統(tǒng)的嚴(yán)格類(lèi)型數(shù)據(jù)庫(kù)中不可能做的事情。
存儲(chǔ)在SQLite數(shù)據(jù)庫(kù)中的每個(gè)值(或由數(shù)據(jù)庫(kù)引擎操作)都有以下存儲(chǔ)類(lèi)之一:
- NULL:表示空值
- INTEGER:該值是一個(gè)有符號(hào)整數(shù),根據(jù)值的大小存儲(chǔ)在1、2、3、4、6或8個(gè)字節(jié)中。
- REAL:該值為浮點(diǎn)值,存儲(chǔ)為8字節(jié)的IEEE浮點(diǎn)數(shù)。
- TEXT:文本字符串,使用數(shù)據(jù)庫(kù)編碼(UTF-8、UTF-16BE或UTF-16LE)存儲(chǔ)。
- BLOB:該值是一組數(shù)據(jù),存儲(chǔ)方式與輸入時(shí)完全相同。
SQLite沒(méi)有單獨(dú)的布爾存儲(chǔ)類(lèi)。相反,布爾值存儲(chǔ)為整數(shù)0 (false)和1 (true)。
存儲(chǔ)類(lèi)比數(shù)據(jù)類(lèi)型更通用。例如,整數(shù)存儲(chǔ)類(lèi)包括6種不同長(zhǎng)度的整數(shù)數(shù)據(jù)類(lèi)型。這在磁盤(pán)上造成了不同。但是一旦整數(shù)值從磁盤(pán)讀取到內(nèi)存中進(jìn)行處理,它們就會(huì)被轉(zhuǎn)換為最通用的數(shù)據(jù)類(lèi)型(8字節(jié)有符號(hào)整數(shù))。因此,在大多數(shù)情況下,“存儲(chǔ)類(lèi)”與“數(shù)據(jù)類(lèi)型”是無(wú)法區(qū)分的,這兩個(gè)術(shù)語(yǔ)可以互換使用。
SQLite version 3數(shù)據(jù)庫(kù)中的任何列,除了整數(shù)主鍵列之外,都可以用來(lái)存儲(chǔ)任何存儲(chǔ)類(lèi)的值。
假設(shè)在接下要構(gòu)建的寵物應(yīng)用中將存儲(chǔ)的寵物信息有:Name(姓名)、Breed(品種)、Gender(性別)、Weight(體重/千克),并在 SQLite 數(shù)據(jù)庫(kù)系統(tǒng)中使用如下存儲(chǔ)類(lèi)來(lái)存儲(chǔ)寵物的每個(gè)信息。
- Name:使用 TEXT 存儲(chǔ)類(lèi)存儲(chǔ)字符串
- Breed:可選,由于不確定會(huì)有多少個(gè)品種寵物,使用 TEXT 字符串存儲(chǔ)類(lèi)
- Gender:性別有三種情況:0 (未知)、1(男)、2(女),因此使用 INTEGER 存儲(chǔ)類(lèi)更好
- Weight:這里假設(shè)不存在小數(shù)的情況,所以使用 INTEGER 存儲(chǔ)類(lèi)
設(shè)計(jì)和創(chuàng)建數(shù)據(jù)庫(kù)
下面將創(chuàng)建一個(gè) 存儲(chǔ)耳機(jī)信息的 SQLite數(shù)據(jù)庫(kù)作為示例。
首先,使用 sqlite3 新建一個(gè)名為 store.db 的數(shù)據(jù)庫(kù)文件:
PS C:\Users\blood\Desktop> sqlite3.exe shelter.db SQLite version 3.32.2 2020-06-04 12:58:43 Enter ".help" for usage hints. sqlite> .tables sqlite>新建數(shù)據(jù)表語(yǔ)法參考:
CREATE TABLE <table_name>( <column_name_1> <data_type_1>, <column_name_2> <data_type_2>, ...);創(chuàng)建 headphones 數(shù)據(jù)表,用于存儲(chǔ)耳機(jī)的相關(guān)信息。
sqlite> CREATE TABLE headphones(_id INTEGER,...> name TEXT,...> price INTEGER,...> style INTEGER,...> in_stock INTEGER,...> description TEXT); sqlite> .tables headphones sqlite> .schema headphones CREATE TABLE headphones(_id INTEGER, name TEXT, price INTEGER, style INTEGER, in_stock INTEGER, description TEXT); sqlite> PRAGMA TABLE_INFO(headphones); 0|_id|INTEGER|0||0 1|name|TEXT|0||0 2|price|INTEGER|0||0 3|style|INTEGER|0||0 4|in_stock|INTEGER|0||0 5|description|TEXT|0||0 sqlite> DROP TABLE headphones; sqlite> .tables sqlite>最后,要為寵物應(yīng)用在 shelter.db 數(shù)據(jù)庫(kù)中創(chuàng)建 pets 數(shù)據(jù)表:
其中 _id 字段作為每個(gè)寵物的唯一標(biāo)識(shí)。
CREATE TABLE pets (_id INTEGER, name TEXT, breed TEXT, gender INTEGER, weight INTEGER);快速提示
這里給出幾個(gè) SQLite 數(shù)據(jù)庫(kù)中的提示。
CRUD
CURD 概述
創(chuàng)建好表格后就可以向表格中添加行,并讀取和操縱其中的數(shù)據(jù),對(duì)表格執(zhí)行的基本操作可以總結(jié)為一個(gè)詞 CRUD。
CRUD 是與數(shù)據(jù)庫(kù)相關(guān)的縮寫(xiě),表示 Create(創(chuàng)建)、Read(讀取)、Update(更新)和 Delete(刪除)
插入 INSERT
INSERT 語(yǔ)句:
INSERT INTO <table_name>( <column_name_1>, <column_name_2>, …) VALUES ( <values_1>, <values_2>, …);創(chuàng)建寵物表格
CREATE TABLE pets (_id, name, breed, gender, weight);在第 1 行插入關(guān)于 Tommy 的信息
INSERT INTO pets (_id, name, breed, gender, weight) VALUES (1, "Tommy", "Pomeranian", 1, 4);在第 2 行插入關(guān)于 Garfield 的數(shù)據(jù)
INSERT INTO pets (_id, name, breed, gender, weight) VALUES (2, "Garfield", "Tabby", 1, 8);將模式改成 column
.mode column顯示表頭
.header on從寵物表格中讀取所有的列和行
SELECT * FROM pets;結(jié)果
_id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 8表格的局限
現(xiàn)在 pets 表格中已經(jīng)有了兩條數(shù)據(jù):
sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 8現(xiàn)在 再插入一條數(shù)據(jù):
sqlite> INSERT INTO pets (_id, name, breed, gender, weight) VALUES (1, "Binx", "Bomboy", 1, 5); sqlite> sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 8 1 Binx Bomboy 1 5從輸出內(nèi)容可以看出,本來(lái)應(yīng)該唯一的 _id 字段不再唯一。
如果再傳入一條數(shù)據(jù),并且忘記指定 寵物的名稱(chēng):
sqlite> INSERT INTO pets (_id, breed, gender, weight) VALUES (3, "Bomboy", 1, 5); sqlite> sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 8 1 Binx Bomboy 1 5 3 Bomboy 1 5現(xiàn)在可以看到 id 為 3 的寵物姓名沒(méi)有值,這在寵物收容所中是不應(yīng)該存在的情況。
SQL 提供了一些便捷的關(guān)鍵字,幫助我們避免出現(xiàn) 上述情況,比如:
- PRIMARY KEY:確保唯一性。每個(gè)表只能有一個(gè)主鍵。
- AUTOINCREMENT:自動(dòng)計(jì)算新的整數(shù)值,一般用于 ID 列。
- NOT NULL:當(dāng)一個(gè)值被插入到表中時(shí),它必須有一個(gè)與其相關(guān)聯(lián)的值。
- DEFAULT <value>:當(dāng)插入新行時(shí),如果沒(méi)有提供值,則使用“默認(rèn)值”。
這只是一部分,并沒(méi)有列全,但對(duì)應(yīng) pets 表格來(lái)說(shuō)已經(jīng)夠夠用了。
我們希望 pets 數(shù)據(jù)表的 id 字段作為唯一標(biāo)識(shí),并且 name 字段不能為空,在相應(yīng)的字段后 添加約束條件。
先使用 SQL 命令 DROP TABLE pets; 刪除已有的數(shù)據(jù)表,然后重新創(chuàng)建 pets 數(shù)據(jù)表:
sqlite> DROP TABLE pets; sqlite> sqlite> CREATE TABLE pets(...> _id INTEGER PRIMARY KEY AUTOINCREMENT,...> name TEXT NOT NULL,...> breed TEXT,...> gender INTEGER,...> weight INTEGER); sqlite> sqlite> PRAGMA TABLE_INFO(pets); cid name type notnull dflt_value pk ---------- ---------- ---------- ---------- ---------- ---------- 0 _id INTEGER 0 1 1 name TEXT 1 0 2 breed TEXT 0 0 3 gender INTEGER 0 0 4 weight INTEGER 0 0這時(shí) id 字段已經(jīng)可以自增長(zhǎng),所以在插入數(shù)據(jù)時(shí)不必 指定 id 字段的值:
sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Tommy", "Pomeranian", 1, 4); sqlite> sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Garfield", "Tabby", 1, 8); sqlite> sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 8如果插入一條 id 已經(jīng)存在的數(shù)據(jù),則會(huì)報(bào)錯(cuò),因?yàn)?id 應(yīng)該唯一,比如 1:
sqlite> INSERT INTO pets (_id, name, breed, gender, weight) VALUES (1, "Binx", "Bomboy", 1, 5); Error: UNIQUE constraint failed: pets._id同樣的,插入一條 name 字段為空的數(shù)據(jù)也會(huì)報(bào)錯(cuò),因?yàn)椴辉试S為空:
sqlite> INSERT INTO pets (_id, breed, gender, weight) VALUES (3, "Bomboy", 1, 5); Error: NOT NULL constraint failed: pets.name下面對(duì) pets 表中剩下的幾個(gè)字段添加約束(先刪除現(xiàn)有的 pets 數(shù)據(jù)表)。
sqlite> DROP TABLE pets; sqlite> sqlite> CREATE TABLE pets (...> _id INTEGER PRIMARY KEY AUTOINCREMENT,...> name TEXT NOT NULL,...> breed TEXT,...> gender INTEGER NOT NULL,...> weight INTEGER NOT NULL DEFAULT 0); sqlite> sqlite> PRAGMA TABLE_INFO(pets); cid name type notnull dflt_value pk ---------- ---------- ---------- ---------- ---------- ---------- 0 _id INTEGER 0 1 1 name TEXT 1 0 2 breed TEXT 0 0 3 gender INTEGER 1 0 4 weight INTEGER 1 0 0解釋:
CREATE TABLE用來(lái)創(chuàng)建新的表格的 SQL 關(guān)鍵字
pets指的是要?jiǎng)?chuàng)建的表格的名稱(chēng)
_id INTEGER PRIMARY KEY AUTOINCREMENT,表格的第一列將稱(chēng)為 _id,類(lèi)型為 INTEGER。因?yàn)槲覀兿M麑⑵渥鳛楸砀裥械?ID,所以使用關(guān)鍵字 PRIMARY KEY。當(dāng)新的行創(chuàng)建后,我們希望 ID 能自動(dòng)按升序增大,所以使用關(guān)鍵字 AUTOINCREMENT。
name TEXT NOT NULL,名稱(chēng)的數(shù)據(jù)類(lèi)型為 TEXT。我們用關(guān)鍵字 NOT NULL 表明此列必須具有值。
breed TEXT,品種的數(shù)據(jù)為 TEXT。因?yàn)槭沁x填的,所以我們不需要關(guān)鍵字 NOT NULL
gender INTEGER NOT NULL,性別的數(shù)據(jù)類(lèi)型為 INTEGER(0 - 未知,1 - 公,2 - 母)。我們用關(guān)鍵字 NOT NULL 表明此列必須具有值。
weight INTEGER NOT NULL DEFAULT 0);體重的數(shù)據(jù)類(lèi)型為 INTEGER。我們用關(guān)鍵字 NOT NULL 表明此列必須具有值。我們用 DEFAULT 0 表示默認(rèn)值將為 0(如果未提供)。
選擇、位置和排序
當(dāng)數(shù)據(jù)表中的數(shù)據(jù) 有很多時(shí),我們可能只關(guān)心 滿足特定條件的 信息,比如 5 歲以上的寵物、不足 18 千克的寵物,或是同時(shí)滿足多個(gè)條件的寵物。
在此之前先插入一些數(shù)據(jù):
sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ( "Tommy", "Pomeranian", 1, 4); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Garfield", "Tabby", 1, 14); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Binx", "Bombay", 1, 6); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ( "Lady", "Cocker Spaniel", 2, 14); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Duke", "Unknown", 1, 70); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Cat", "Tabby", 0, 7); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Baxter", "Border Terrier", 1, 8); sqlite> INSERT INTO pets (name, gender, weight) VALUES ("Arlene", 2, 5); sqlite> sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 4 2 Garfield Tabby 1 14 3 Binx Bombay 1 6 4 Lady Cocker Spa 2 14 5 Duke Unknown 1 70 6 Cat Tabby 0 7 7 Baxter Border Ter 1 8 8 Arlene 2 5WHERE 關(guān)鍵字可以指定要查詢(xún)的條件,WHERE 子句確保只有符合指定條件的行受到影響,可以與 SELECT、INSERT、UPDATE或DELETE語(yǔ)句一起使用。
分別查詢(xún) id 等于 3 和 體重大于等于 18 千克的寵物
sqlite> SELECT * FROM pets WHERE _id == 3; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 3 Binx Bombay 1 6 sqlite> sqlite> SELECT * FROM pets WHERE weight >= 18; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 5 Duke Unknown 1 70使用 AND 關(guān)鍵字來(lái)組合查詢(xún)條件:
性別為雄性,且 體重大于 10 千克的寵物
sqlite> SELECT * FROM pets WHERE gender == 1 AND weight > 10; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 2 Garfield Tabby 1 14 5 Duke Unknown 1 70ORDER BY 對(duì)查詢(xún)結(jié)果進(jìn)行排序根據(jù)列出的列,按升序(ASC)或降序(DESC)對(duì)數(shù)據(jù)進(jìn)行排序:
sqlite> SELECT * FROM pets WHERE _id <= 5 ORDER BY name; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 3 Binx Bombay 1 6 5 Duke Unknown 1 70 2 Garfield Tabby 1 14 4 Lady Cocker Spa 2 14 1 Tommy Pomeranian 1 4查詢(xún) 雌性寵物的 姓名和體重,并按體重從高到底排序:
sqlite> SELECT name, weight FROM pets WHERE gender == 2 ORDER BY weight DESC; name weight ---------- ---------- Lady 14 Arlene 5更新 UPDATE
有一只寵物的體重超過(guò)了 50 千克,寵物管理員對(duì)它進(jìn)行了減肥,這時(shí)就需要在寵物信息表中 更改這只寵物的體重信息 為 40 千克。
sqlite> SELECT _id, name, weight FROM pets WHERE weight > 50; _id name weight ---------- ---------- ---------- 5 Duke 70更改表中的數(shù)據(jù)可以使用 UPDATE 語(yǔ)句實(shí)現(xiàn),語(yǔ)法:
UPDATE <table_name> SET <column_name> = <value> WHERE <condition>;使用 UPDATE 語(yǔ)句更新 寵物的體重值:
sqlite> UPDATE pets SET weight = 40 WHERE _id = 5; sqlite> sqlite> SELECT _id, name, weight FROM pets WHERE _id = 5; _id name weight ---------- ---------- ---------- 5 Duke 40有一天,寵物收容所的稱(chēng)出了問(wèn)題,所有寵物都要進(jìn)行重新稱(chēng)重,在這之前需要把所有寵物 的體重改為 0 千克:
sqlite> UPDATE pets SET weight = 0; sqlite> sqlite> SELECT _id, name, weight FROM pets; _id name weight ---------- ---------- ---------- 1 Tommy 0 2 Garfield 0 3 Binx 0 4 Lady 0 5 Duke 0 6 Cat 0 7 Baxter 0 8 Arlene 0刪除 DELETE
最后要了解的數(shù)據(jù)庫(kù)操作是將所有錯(cuò)誤地輸入輸入到數(shù)據(jù)庫(kù)中的寵物刪掉。
DELETE 語(yǔ)句可以實(shí)現(xiàn)從表中刪除數(shù)據(jù),語(yǔ)法:
DELETE FROM <table_name> WHERE <condition>;這是為刪除任何數(shù)據(jù)之前的 所有寵物信息:
sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 0 2 Garfield Tabby 1 0 3 Binx Bombay 1 0 4 Lady Cocker Spa 2 0 5 Duke Unknown 1 0 6 Cat Tabby 0 0 7 Baxter Border Ter 1 0 8 Arlene 2 0下面將 性別 未知的寵物信息:
sqlite> DELETE FROM pets WHERE gender = 0; sqlite> sqlite> SELECT * FROM pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 0 2 Garfield Tabby 1 0 3 Binx Bombay 1 0 4 Lady Cocker Spa 2 0 5 Duke Unknown 1 0 7 Baxter Border Ter 1 0 8 Arlene 2 0寵物性別為 雄性 且 id 大于 5 的寵物信息有誤,需要進(jìn)行刪除:
sqlite> DELETE FROM pets WHERE gender = 1 AND _id > 5; sqlite> sqlite> select * from pets; _id name breed gender weight ---------- ---------- ---------- ---------- ---------- 1 Tommy Pomeranian 1 0 2 Garfield Tabby 1 0 3 Binx Bombay 1 0 4 Lady Cocker Spa 2 0 5 Duke Unknown 1 0 8 Arlene 2 0如果 店內(nèi)所有的寵物都 被人領(lǐng)養(yǎng)走了,則需要?jiǎng)h除所有的寵物信息:
sqlite> DELETE FROM pets; sqlite> sqlite> SELECT * FROM pets; sqlite>總結(jié)
現(xiàn)在已經(jīng)知道如何處理數(shù)據(jù)庫(kù)中的數(shù)據(jù)了,先創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù),然后在其中創(chuàng)建了數(shù)據(jù)表。然后討論了如何向表格中插入行,并更新和刪除這些行。接著又 使用了 WHERE 條件 和 ORDER BY 排序 來(lái)查詢(xún)數(shù)據(jù),并獲得關(guān)心的行和列。
SQLite 中的存儲(chǔ)類(lèi)的使用十分靈活,即使聲明了字段的存儲(chǔ)類(lèi),也仍然可以插入任意類(lèi)型的值,這也解釋了為什么創(chuàng)建表時(shí)可以不=聲明字段類(lèi)型。
參考
計(jì)算機(jī)內(nèi)存和硬盤(pán)存儲(chǔ)空間之間的區(qū)別
數(shù)據(jù)和文件存儲(chǔ)概覽
關(guān)于 SQL 和 SEQUEL 之間區(qū)別的有趣討論:
有些人發(fā)成“S-Q-L”,有些人叫成“sequel”,都指的是同一概念。追溯下歷史:縮寫(xiě)“SEQUEL”后來(lái)改成了 SQL,因?yàn)椤盨EQUEL“是一家英國(guó)航空公司 Hawker Siddeley 的商標(biāo)
SQL 維基百科界面
詳細(xì)了解 SQLite 中的數(shù)據(jù)類(lèi)型,請(qǐng)點(diǎn)擊此處。
Command Line Shell For SQLite
總結(jié)
以上是生活随笔為你收集整理的安卓学习日志 Day15 — 数据库基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java添加按钮点击事件_如何为odoo
- 下一篇: 使用 Metasploit 利用 MyS