數據庫基本概念
1、數據庫( DataBase,DB)
存放數據的地方,特點是數據按照數據模型組織,是高度結構化的,可供多個用戶共享並具有一定的安全性。
2、關係型數據庫
按照二維表結構方式組織的數據集合,二維表由行和列組成,表的行稱爲元組,列稱爲屬性,對錶的操作稱爲關係運算,主要的關係運算有投影、選擇和連接等。
3、數據庫管理系統(DataBase Management System,DBMS)
它是位於用戶應用程序和操作系統之間的數據庫管理系統軟件,其主要功能是組織、存儲和管理數據,高效地訪問和維護數據,即提供數據定義、數據操縱、數據控制和數據維護等功能。常用的數據庫管理系統有Oracle、Microsoft SQL Server和MySQL等。
4、數據庫系統(DataBase System,DBS)
指按照數據庫方式存儲和維護數據,並嚮應用程序提供數據訪問接口的系統
DBS通常由數據庫、計算機硬件(支持DB存儲和訪問)、軟件(包括操作系統、DBMS及應用開發支撐軟件)和數據庫管理員(DataBase Administrator,DBA)四個部分組成。
分爲兩類:桌面型和網絡型
桌面型數據庫系統指只在本機運行、不與其他計算機交換數據的系統,常用於小型信息管理系統,這類數據庫系統的典型代表是VFP和Access。
網絡型數據庫系統指通過計算機網絡進行數據共享和交換的系統,常用於構建較複雜的C/S結構或B/S結構的分佈式應用系統,大多數數據庫系統均屬於此類,如Oracle、Microsoft SQL Sever等。
5、結構化查詢語言SQL
結構化查詢語言(Structured Query Language,SQL)是用於關係數據庫操作的標準語言,最早由Boyce和Chambedin在1974年提出,稱爲SEQUEL語言。
SQL語言由以下三部分組成。
(1)數據定義語言(Data Description Language,DDL),用於執行數據庫定義的任務,對數據庫及數據庫中的各種對象進行創建、刪除和修改等操作。數據庫對象主要包括表、默認約束、規則、視圖、觸發器和存儲過程等。
(2)數據操縱語言(Data Manipulation Language,DML),用於操縱數據庫中各種對象,檢索和修改數據。
(3)數據控制語言(Data Control Language,DCL),用於安全管理,確定哪些用戶可以查看或修改數據庫中的數據。
6、數據庫的增刪改查
查詢語句 SELECT
(1)查詢Student數據庫。查詢students表中各個同學的姓名和總學分。
USE Student SELECT name,totalscore FROM students
(2)查詢表中所有記錄。查詢students表中各個同學的所有信息。
SELECT * FROM students
(3)條件查詢。查詢students表中總學分大於等於120的同學的情況。
SELECT * FROM students
WHERE totalscore >= 120
(4)多重條件查詢。查詢students表中所在係爲“計算機”且總學分大於等於120的同學的情況。
SELECT * FROM students
WHERE department='計算機' AND totalscore >= 120
(5)使用LIKE謂詞進行模式匹配。查詢students表中姓“王”且單名的學生情況。
SELECT * FROM students
WHERE name LIKE '王_'
(6)用BETWEEN…AND指定查詢範圍。查詢students表中不在1999年出生的學生情況。
SELECT * FROM students
WHERE birthday NOT BETWEEN '1999-1-1' and '1999-12-31'
(7)空值比較。查詢總學分尚不確定的學生情況。
SELECT * FROM students
WHERE totalscore IS NULL
(8)自然連接查詢。查找計算機系學生姓名及其“C程序設計”課程的考試分數情況。
SLELCT name,grade
FROM students, courses,grades,
WHERE department = '計算機' AND coursename= ' C程序設計' AND
students.studentid = grades.studentid AND courses.courseid =
grades.coursesid
(9)IN子查詢。查找選修了課程號爲101的學生情況。
SELECT * FROM students
WHERE studentid IN
( SELECT studentid FROM courses WHERE courseid = '101' )
在執行包含子查詢的SELECT語句時,系統首先執行子查詢,產生一個結果表,再執行外查詢。本例中,首先執行子查詢:
SELECT studentid FROM courses, students,grades WHERE courseid = '101'
AND students.studentid = grades.studentid AND courses.courseid =
grades.coursesid
得到一個只含有studentid列的結果表,courses中courseid列值爲101的行在該結果表中都有一行。
(10)比較子查詢。這種子查詢可以認爲是IN子查詢的擴展,它是表達式的值與子查詢的結果進行比較運算。查找課程號206的成績不低於課程號101的最低成績的學生學號。
SELECT studentid FROM grades
WHERE courseid = '206' AND grade !< ANY
( SELECT grade FROM grades WHERE courseid = '101')
(11)EXISTS子查詢。EXISTS謂詞用於測試子查詢的結果是否爲空表,若子查詢的結果集不爲空,則EXISTS返回TRUE,否則返回FALSE。EXISTS還可與NOT結合使用,即NOT EXISTS,其返回值與EXISTS剛好相反。查找選修206號課程的學生姓名。
SELECT name FROM students
WHERE EXISTS
( SELECT * FROM grades
WHERE studentid = students.studentid AND courseid = '206'
)
(12)查找選修了全部課程的同學姓名(即查找沒有一門功課不選修的學生)。
SELECT name FROM students
WHERE NOT EXISTS
( SELECT * FROM courses
WHERE NOT EXISTS
( SELECT * FROM grades
WHERE studentid= students.studentid
AND courseid=courses.courseid)
)
(13)查詢結果分組。將各課程成績按學號分組。
SELECT studentid,grade FROM grades
GROUP BY studentid
(14)查詢結果排序。將計算機系的學生按出生時間先後排序。
SELECT * FROM students
WHERE department = '計算機'
ORDER BY birthday
(15)聚合函數的使用
// 求選修101課程學生的平均成績。
SELECT AVG(grade) AS ' 課程101平均成績'
FROM grades
WHERE courseid = '101'
// 求選修101課程學生的最高分和最低分。
SELECT MAX(grade) AS '課程101最高分' , MIN(grade) AS '課程101最低分'
FROM grades
WHERE courseid = '101'
// 求學生的總人數。
SELECT COUNT(*) AS '學生總數'
FROM students
插入語句 INSERT
INSERT可添加一條或多條記錄至一個表中。
INSERT有兩種語法形式。
語法1:
INSERT INTO target [IN externaldatabase] (fields_list)
{DEFAULT VALUES|VALUES(DEFAULT|expression_list)}
語法2:
INSERT INTO target [IN externaldatabase] fields_list
{SELECT…|EXECUTE…}
第1種形式將一個記錄或記錄的部分字段插入到表或視圖中。
第2種形式的INSERT語句插入來自SELECT語句或來自使用EXECUTE語句執行的存儲過程的結果集。
例如,用以下語句向students表添加一條記錄:
INSERT INTO students
VALUES('170206','羅亮', 0 ,'1/30/1998', 1, 150)
刪除語句 DELETE
DELETE用於從一個或多個表中刪除記錄。
DELETE語句的語法格式如下:
DELETE FROM table_names [WHERE…]
例如,用以下語句從students表中刪除姓名爲“羅亮”的記錄:
DELETE FROM students
WHERE name = '羅亮'
數據庫操作
QT提供QtSql模塊實現對數據庫的訪問,同時提供調用接口。
SQLite數據庫介紹:
Qt提供了一種進程內數據庫SQLite。它小巧靈活,無須額外安裝配置且支持大部分ANSI SQL92標準,是一個輕量級的數據庫。
概括起來具有以下優點。
(1)SQLite的設計目的是嵌入式SQL數據庫引擎,它基於純C語言代碼,已經應用於非常廣泛的領域內。
(2)SQLite在需要持久存儲時可以直接讀寫硬盤上的數據文件,在無須持久存儲時也可以將整個數據庫置於內存中,兩者均不需要額外的服務器端進程,即SQLite是無須獨立運行的數據庫引擎。
(3)開放源代碼,整個代碼少於3萬行,有良好的註釋和90%以上的測試覆蓋率。
(4)少於250KB的內存佔用容量(gcc編譯情況下)。
(5)支持視圖、觸發器和事務,支持嵌套SQL功能。
(6)提供虛擬機用於處理SQL語句。
(7)不需要配置,不需要安裝,也不需要管理員。
(8)支持大部分ANSI SQL92標準。
(9)大部分應用的速度比目前常見的客戶端/服務器結構的數據庫快。
(10)編程接口簡單易用。
QtSql模塊使用驅動插件(driver plugins)與不同的數據庫接口通信
以SQLite數據庫爲例
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());// 設置顯示中文
QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE"); // 訪問QSQLITE驅動
db.setHostName("easybook-3313b0"); // 設置數據庫主機名
db.setDatabaseName("qtDB.db"); // 設置數據庫名
db.setUserName("zhouhejun"); // 設置數據庫用戶名
db.setPassword("123456"); // 設置數據庫密碼
db.open(); // 打開連接
//創建數據庫表
QSqlQuery query;
bool success=query.exec("create table automobil(id int primary key,attribute varchar,type varchar,kind varchar,nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
if(success)
qDebug()<<QObject::tr("數據庫表創建成功!\n");
else
qDebug()<<QObject::tr("數據庫表創建失敗!\n");
//查詢
query.exec("select * from automobil");
QSqlRecord rec = query.record();
qDebug() << QObject::tr("automobil表字段數:" )<< rec.count();
//插入記錄
QTime t;
t.start();
query.prepare("insert into automobil values(?,?,?,?,?,?,?,?,?,?)");
long records=100;
for(int i=0;i<records;i++)
{
query.bindValue(0,i);
query.bindValue(1,"四輪");
query.bindValue(2,"轎車");
query.bindValue(3,"富康");
query.bindValue(4,rand()%100);
query.bindValue(5,rand()%10000);
query.bindValue(6,rand()%300);
query.bindValue(7,rand()%200000);
query.bindValue(8,rand()%52);
query.bindValue(9,rand()%100);
success=query.exec();
if(!success)
{
QSqlError lastError=query.lastError();
qDebug()<<lastError.driverText()<<QString(QObject::tr("插入失敗"));
}
}
qDebug()<<QObject::tr("插入 %1 條記錄,耗時:%2 ms").arg(records).arg(t.elapsed());
//排序
t.restart();
success=query.exec("select * from automobil order by id desc");
if(success)
qDebug()<<QObject::tr("排序 %1 條記錄,耗時:%2 ms").arg(records).arg(t.elapsed());
else
qDebug()<<QObject::tr("排序失敗!");
//更新記錄
t.restart();
for(int i=0;i<records;i++)
{
query.clear();
query.prepare(QString("update automobil set attribute=?,type=?,"
"kind=?,nation=?,"
"carnumber=?,elevaltor=?,"
"distance=?,oil=?,"
"temperature=? where id=%1").arg(i));
query.bindValue(0,"四輪");
query.bindValue(1,"轎車");
query.bindValue(2,"富康");
query.bindValue(3,rand()%100);
query.bindValue(4,rand()%10000);
query.bindValue(5,rand()%300);
query.bindValue(6,rand()%200000);
query.bindValue(7,rand()%52);
query.bindValue(8,rand()%100);
success=query.exec();
if(!success)
{
QSqlError lastError=query.lastError();
qDebug()<<lastError.driverText()<<QString(QObject::tr("更新失敗"));
}
}
qDebug()<<QObject::tr("更新 %1 條記錄,耗時:%2 ms").arg(records).arg(t.elapsed());
//刪除
t.restart();
query.exec("delete from automobil where id=15");
qDebug()<<QObject::tr("刪除一條記錄,耗時:%1 ms").arg(t.elapsed());