資料庫操作類base
㈠ 請問資料庫有哪些種類呢
資料庫共有3種類型,為關系資料庫、非關系型資料庫和鍵值資料庫。
1、關系資料庫
Mysql、MariaDB(MySQL的代替品,英文維基網路從MySQL轉向MariaDB)、Percona Server(MySQL的代替品·)、PostgreSQL、Microsoft Access、Microsoft SQL Server、Google Fusion Tables、FileMaker、Oracle資料庫、Sybase、dBASE、Clipper、FoxPro、foshub。
幾乎所有的資料庫管理系統都配備了一個開放式資料庫連接(ODBC)驅動程序,令各個資料庫之間得以互相集成。
2、非關系型資料庫(NoSQL)
BigTable(Google)、Cassandra、MongoDB、CouchDB。
3、鍵值(key-value)資料庫
Apache Cassandra(為Facebook所使用):高度可擴展、Dynamo、LevelDB(Google)。
(1)資料庫操作類base擴展閱讀:
資料庫模型:對象模型、層次模型(輕量級數據訪問協議)、網狀模型(大型數據儲存)、關系模型、面向對象模型、半結構化模型、平面模型(表格模型,一般在形式上是一個二維數組。如表格模型數據Excel)。
資料庫的架構可以大致區分為三個概括層次:內層、概念層和外層。
㈡ 資料庫有哪些種類分別是干什麼用的
資料庫共有3種類型,為關系資料庫、非關系型資料庫和鍵值資料庫。
1、關系資料庫
MySQL、MariaDB(MySQL的代替品,英文維基網路從MySQL轉向MariaDB)、Percona Server(MySQL的代替品·)、PostgreSQL、Microsoft Access、Microsoft SQL Server、Google Fusion Tables、FileMaker、Oracle資料庫、Sybase、dBASE、Clipper、FoxPro、foshub。
幾乎所有的資料庫管理系統都配備了一個開放式資料庫連接(ODBC)驅動程序,令各個資料庫之間得以互相集成。
2、非關系型資料庫(NoSQL)
BigTable(Google)、Cassandra、MongoDB、CouchDB。
3、鍵值(key-value)資料庫
Apache Cassandra(為Facebook所使用):高度可擴展、Dynamo、LevelDB(Google)。
(2)資料庫操作類base擴展閱讀:
資料庫模型:對象模型、層次模型(輕量級數據訪問協議)、網狀模型(大型數據儲存)、關系模型、面向對象模型、半結構化模型、平面模型(表格模型,一般在形式上是一個二維數組。如表格模型數據Excel)。
資料庫的架構可以大致區分為三個概括層次:內層、概念層和外層。
㈢ 資料庫有哪些類型
資料庫有兩種類型,分別是關系型資料庫與非關系型資料庫。
資料庫,簡而言之可視為電子化的文件櫃——存儲電子文件的處所,用戶可以對文件中的數據進行新增、截取、更新、刪除等操作。
關系型資料庫主要有:
Oracle、DB2、Microsoft
SQL
Server、Microsoft
Access、MySQL等等。
非關系型資料庫主要有:
NoSql、Cloudant、MongoDb、redis、HBase等等。
(3)資料庫操作類base擴展閱讀:
非關系型資料庫的優勢:
1、性能高:NOSQL是基於鍵值對的,可以想像成表中的主鍵和值的對應關系,而且不需要經過SQL層的解析,所以性能非常高。
2、可擴展性好:同樣也是因為基於鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。
關系型資料庫的優勢:
1、可以復雜查詢:可以用SQL語句方便的在一個表以及多個表之間做非常復雜的數據查詢。
2、事務支持良好:使得對於安全性能很高的數據訪問要求得以實現。
參考資料來源:網路-資料庫
㈣ 資料庫有哪些基本操作
分5類: 查詢語句:select DML(數據操作語言):insert,update,delete,merge DDl(數據定義語言):create.alter,drop,truncateDCL(數據控制語言):revoke,grant事務控制語句:commit,roolback,savepoint
㈤ MFC操作資料庫有關的類
1、 MFC的ODBC類簡介
MFC的ODBC類對較復雜的ODBC API進行了封裝,提供了簡化的調用介面,從而大大方便了資料庫應用程序的開發。程序員不必了解ODBC API和SQL的具體細節,利用ODBC類即可完成對資料庫的大部分操作。
MFC的ODBC類主要包括:
CDatabase類:主要功能是建立與數據源的連接。
CRecordset類:該類代表從數據源選擇的一組記錄(記錄集),程序可以選擇數據源中的某個表作為一個記錄集,也可以通過對表的查詢得到記錄集,還可以合並同一數據源中多個表的列到一個記錄集中.通過該類可對記錄集中的記錄進行滾動、修改、增加和刪除等操作。
CRecordView類:提供了一個表單視圖與某個記錄集直接相連,利用對話框數據交換機制(DDX)在記錄集與表單視圖的控制項之間傳輸數據。該類支持對記錄的瀏覽和更新,在撤銷時會自動關閉與之相聯系的記錄集。
CFieldExchange類:支持記錄欄位數據交換(DFX),即記錄集欄位數據成員與相應的資料庫的表的欄位之間的數據交換。該類的功能與CDataExchange類的對話框數據交換功能類似。
CDBException類:代表ODBC類產生的異常。
概括地講,CDatabase針對某個資料庫,它負責連接數據源;CRecordset針對數據源中的記錄集,它負責對記錄的操作;CRecordView負責界面,而CFieldExchange負責CRecordset與數據源的數據交換。
利用AppWizard和ClassWizard,用戶可以方便地建立資料庫應用程序,但這並不意味著可以對MFC的ODBC類一無所知.讀者應注意閱讀後面幾小節中的內容,為學習後面的例子打好基礎.
2、 CDatabase類
要建立與數據源的連接,首先應構造一個CDatabase對象,然後再調用CDatabase的Open成員函數.Open函數負責建立連接,其聲明為
virtual BOOL Open( LPCTSTR lpszDSN, BOOL bExclusive = FALSE, BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = 「ODBC;」, BOOL bUseCursorLib = TRUE ); throw( CDBException, CMemoryException );
參數lpszDSN指定了數據源名(構造數據源的方法將在後面介紹),在lpszConnect參數中也可包括數據源名,此時lpszDSN必需為 NULL,若在函數中未提供數據源名且使lpszDSN為NULL,則會顯示一個數據源對話框,用戶可以在該對話框中選擇一個數據源.參數 bExclusive說明是否獨占數據源,由於目前版本的類庫還不支持獨占方式,故該參數的值應該是FALSE,這說明數據源是被共享的.參數 bReadOnly若為TRUE則對數據源的連接是只讀的.參數lpszConnect指定了一個連接字元串,連接字元串中可以包括數據源名、用戶帳號 (ID)和口令等信息,字元串中的"ODBC"表示要連接到一個ODBC數據源上.參數bUseCursorLib若為TRUE,則會裝載游標庫,否則不 裝載,快照需要游標庫,動態集不需要游標庫. 若連接成功,函數返回TRUE,若返回FALSE,則說明用戶在數據源對話框中按了Cancel按鈕。若函數內部出現錯誤,則框架會產生一個異常。
下面是一些調用Open函數的例子。
CDatabase m_db; //在文檔類中嵌入一個CDatabase對象
//連接到一個名為"Student Registration"的數據源
m_db.Open("Student Registration");
//在連接數據源的同時指定了用戶帳號和口令
m_db.Open(NULL,FALSE,FALSE,"ODBC;DSN=Student Registration;UID=ZYF;PWD=1234");
m_db.Open(NULL); //將彈出一個數據源對話框
要從一個數據源中脫離,可調用函數Close。在脫離後,可以再次調用Open函數來建立一個新的連接.調用IsOpen可判斷當前是否有一個連接,調用GetConnect可返回當前的連接字元串。函數的聲明為
virtual void Close( );
BOOL IsOpen( ) const; //返回TRUE則表明當前有一個連接
const CString& GetConnect( ) const;
CDatabase的析構函數會調用Close,所以只要刪除了CDatabase對象就可以與數據源脫離。
3、CRecordset類
CRecordset類代表一個記錄集.該類是MFC的ODBC類中最重要、功能最強大的類。
10.5.1 動態集、快照、游標和游標庫
在多任務操作系統或網路環境中,多個用戶可以共享同一個數據源。共享數據的一個主要問題是如何協調各個用戶對數據源的修改。例如,當某一個應用改變了數 據源中的記錄時,別的連接至該數據源的應用應該如何處理。對於這個問題,基於MFC的ODBC應用程序可以採取幾種不同的處理辦法,這將由程序採用哪種記 錄集決定。
記錄集主要分為快照(Snapshot) 和動態集(Dynaset)兩種,CRecordset類對這兩者都支持。這兩種記錄集的不同表現在它們對別的應用改變數據源記錄採取了不同的處理方法。
快照型記錄集提供了對數據的靜態視.快照是個很形象的術語,就好象對數據源的某些記錄照了一張照片一樣.當別的用戶改變了記錄時(包括修改、添加和刪 除),快照中的記錄不受影響,也就是說,快照不反映別的用戶對數據源記錄的改變.直到調用了CRecordset::Requery重新查詢後,快照才會 反映變化.對於象產生報告或執行計算這樣的不希望中途變動的工作,快照是很有用的。需要指出的是,快照的這種靜態特性是相對於別的用戶而言的,它會正確反 映由本身用戶對記錄的修改和刪除,但對於新添加的記錄直到調用Requery後才能反映到快照中.
動態集提供了數據的動態視.當別的用戶修改或刪除了記錄集中的記錄時,會在動態集中反映出來:當滾動到修改過的記錄時對其所作的修改會立即反映到動態集 中,當記錄被刪除時,MFC代碼會跳過記錄集中的刪除部分.對於其它用戶添加的記錄,直到調用Requery時,才會在動態集中反映出來。本身應用程序對 記錄的修改、添加和刪除會反映在動態集中。當數據必須是動態的時侯,使用動態集是最適合的。例如,在一個火車票聯網售票系統中,顯然應該用動態集隨時反映 出共享數據的變化。
在記錄集中滾動,需要有一個標志來指明滾動後的位置(當前位置)。ODBC驅動程序會維護一個游標,用來跟蹤記錄集的當前記錄,可以把游標理解成跟蹤記錄集位置的一種機制。
游標庫(Cursor Library)是處於ODBC驅動程序管理器和驅動程序之間的動態鏈接庫(ODBCCR32.DLL).游標庫的主要功能是支持快照以及為底層驅動程序 提供雙向滾動能力,高層次的驅動程序不需要游標庫,因為它們是可滾動的.游標庫管理快照記錄的緩沖區,該緩沖區反映本程序對記錄的修改和刪除,但不反映其 它用戶對記錄的改變,由此可見,快照實際上相當於當前的游標庫緩沖區.
應注 意的是,快照是一種靜態游標(Static Cursor).靜態游標直到滾動到某個記錄才能取得該記錄的數據.因此,要保證所有的記錄都被快照,可以先滾動到記錄集的末尾,然後再滾動到感興趣的第 一個記錄上.這樣做的缺點是滾動到末尾需要額外的開銷,會降低性能.
與快照不同,動態集不用游標庫維持的緩沖區來存放記錄.實際上,動態集是不使用游標庫的,因為游標庫會屏蔽掉一些支持動態集的底層驅動程序功能.動態集是一種鍵集驅動游標(Keyset-Driven Cursor),當打開一個動態集時,驅動程序保存記錄集中每個記錄的鍵.只要游標在動態集中滾動,驅動程序就會通過鍵來從數據源中檢取當前記錄,從而保證選取的記錄與數據源同步.
從上面的分析中可以看出,快照和動態集有一個共同的特點,那就是在建立記錄集後,記錄集中的成員就已經確定了.這就是為什麼兩種記錄集都不能反映別的用戶添加記錄的原因.
10.5.2 域數據成員與數據交換
CRecordset類代表一個記錄集.用戶一般需要用ClassWizard創建一個CRecordset的派生類.ClassWizard可以為派 生的記錄集類創建一批數據成員,這些數據成員與記錄的各欄位相對應,被稱為欄位數據成員或域數據成員.例如,對於表10.2所示的將在後面例子中使用的數 據庫表,ClassWizard會在派生類中加入6個域數據成員
10.5.3 SQL查詢
記錄集的建立實際上主要是一個查詢過程,SQL的SELECT語句用來查詢數據源.在建立記錄集時,CRecordset會根據一些參數構造一個 SELECT語句來查詢數據源,並用查詢的結果創建記錄集.明白這一點對理解CRecordset至關重要.SELECT語句的句法如下:
SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
[ORDER BY m_strSort]
其中table-name是表名,rfx-field-list是選擇的列(欄位).WHERE和ORDER BY是兩個子句,分別用來過濾和排序。下面是SELECT語句的一些例子:
SELECT CourseID, InstructorID FROM Section
SELECT * FROM Section WHERE CourseID=『MATH202』 AND Capacity=15
SELECT InstructorID FROM Section ORDER BY CourseID ASC
其中第一個語句從Section表中選擇CourseID和InstructorID欄位.第二個語句從Section表中選擇CourseID為 MATH202且Capacity等於15的記錄,在該語句中使用了象"AND"或"OR"這樣的邏輯連接符.要注意在SQL語句中引用字元串、日期或時 間等類型的數據時要用單引號括起來,而數值型數據則不用.第三個語句從Section表中選擇InstructorID列並且按CourseID的升序排 列,若要降序排列,可使用關鍵字DESC.
提示:如果列名或表名中包含有空格,則必需用方括弧把該名稱包起來。例如,如果有一列名為「Client Name」,則應該寫成「[Client Name]」。
10.5.4 記錄集的建立和關閉
要建立記錄集,首先要構造一個CRecordset派生類對象,然後調用Open成員函數查詢數據源中的記錄並建立記錄集.在Open函數中,可能會調用GetDefaultConnect和GetDefaultSQL函數.函數的聲明為
CRecordset( CDatabase* pDatabase = NULL);
參數pDatabase指向一個CDatabase對象,用來獲取數據源.如果pDatabase為NULL,則會在Open函數中自動構建一個 CDatabase對象.如果CDatabase對象還未與數據源連接,那麼在Open函數中會建立連接,連接字元串(參見10.3.1)由成員函數 GetDefaultConnect提供.
virtual CString GetDefaultConnect( );
該函數返回預設的連接字元串.Open函數在必要的時侯會調用該函數獲取連接字元串以建立與數據源的連接.一般需要在CRecordset派生類中覆蓋該函數並在新版的函數中提供連接字元串.
virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none );
throw( CDBException, CMemoryException );
該函數使用指定的SQL語句查詢數據源中的記錄並按指定的類型和選項建立記錄集.參數nOpenType說明了記錄集的類型,如表10.3所示,如果要求 的類型驅動程序不支持,則函數將產生一個異常.參數lpszSQL是一個SQL的SELECT語句,或是一個表名.函數用lpszSQL來進行查詢,如果 該參數為NULL,則函數會調用GetDefaultSQL獲取預設的SQL語句.參數dwOptions可以是一些選項的組合,常用的選項在表10.4 中列出.若創建成功則函數返回TRUE,若函數調用了CDatabase::Open且返回FALSE,則函數返回FALSE.
表10.3 記錄集的類型
類型
含義
AFX_DB_USE_DEFAULT_TYPE
使用預設值.
CRecordset::dynaset
可雙向滾動的動態集.
CRecordset::snapshot
可雙向滾動的快照.
CRecordset::dynamic
提供比動態集更好的動態特性,大部分ODBC驅動程序不支持這種記錄集.
CRecordset::forwardOnly
只能前向滾動的只讀記錄集.表10.4 創建記錄集時的常用選項
選項
含義
CRecordset::none
無選項(預設).
CRecordset::appendOnly
不允許修改和刪除記錄,但可以添加記錄.
CRecordset::readOnly
記錄集是只讀的.
CRecordset::skipDeletedRecords
有些資料庫(如FoxPro)在刪除記錄時並不真刪除,而是做個刪除標記,在滾動時將跳過這些被刪除的記錄.virtual CString GetDefaultSQL( );
Open函數在必要時會調用該函數返回預設的SQL語句或表名以查詢數據源中的記錄.一般需要在CRecordset派生類中覆蓋該函數並在新版的函數中提供SQL語句或表名.下面是一些返回字元串的例子.
「Section」 //選擇Section表中的所有記錄到記錄集中
「Section, Course」 //合並Section表和Course表的各列到記錄集中
//對Section表中的所有記錄按CourseID的升序進行排序,然後建立記錄集
「SELECT * FROM Section ORDER BY CourseID ASC」
上面的例子說明,通過合理地安排SQL語句和表名,Open函數可以十分靈活地查詢數據源中的記錄.用戶可以合並多個表的欄位,也可以只選擇記錄中的某些欄位,還可以對記錄進行過濾和排序.
上一小節說過,在建立記錄集時,CRecordset會構造一個SELECT語句來查詢數據源.如果在調用Open時只提供了表名,那麼SELECT語 句還缺少選擇列參數rfx-field-list(參見10.5.3).框架規定,如果只提供了表名,則選擇列的信息從DoFieldExchange中 的RFX語句里提取.例如,如果在調用Open時只提供了"Section"表名,那麼將會構造如下一個SELECT語句:
SELECT CourseID,SectionNo,InstructorID,RoomNo, Schele,Capacity FROM Section
建立記錄集後,用戶可以隨時調用Requery成員函數來重新查詢和建立記錄集.Requery有兩個重要用途:
使記錄集能反映用戶對數據源的改變(參見10.5.1).
按照新的過濾或排序方法查詢記錄並重新建立記錄集.
在調用Requery之前,可調用CanRestart來判斷記錄集是否支持Requery操作.要記住Requery只能在成功調用Open後調用,所以程序應調用IsOpen來判斷記錄集是否已建立.函數的聲明為
virtual BOOL Requery( );throw( CDBException, CMemoryException );
返回TRUE表明記錄集建立成功,否則返回FALSE.若函數內部出錯則產生異常.
BOOL CanRestart( ) const; //若支持Requery則返回TRUE
BOOL IsOpen( ) const; //若記錄集已建立則返回TRUE
CRecordset類有兩個公共數據成員m_strFilter和m_strSort用來設置對記錄的過濾和排序.在調用Open或Requery 前,如果在這兩個數據成員中指定了過濾或排序,那麼Open和Requery將按這兩個數據成員指定的過濾和排序來查詢數據源.
成員m_strFilter用於指定過濾器.m_strFilter實際上包含了SQL的WHERE子句的內容,但它不含WHERE關鍵字.使用m_strFilter的一個例子為:
m_pSet->m_strFilter=「CourseID=『MATH101』」; //只選擇CourseID為MATH101的記錄
if(m_pSet->Open(CRecordset::snapshot, 「Section」))
. . . . . .
成員m_strSort用於指定排序.m_strSort實際上包含了ORDER BY子句的內容,但它不含ORDER BY關鍵字.m_strSort的一個例子為
m_pSet->m_strSort=「CourseID DESC」; //按CourseID的降序排列記錄
m_pSet->Open();
. . . . . .
事實上,Open函數在構造SELECT語句時,會把m_strFilter和m_strSort的內容放入SELECT語句的WHERE和ORDER BY子句中.如果在Open的lpszSQL參數中已包括了WHERE和ORDER BY子句,那麼m_strFilter和m_strSort必需為空.
調用無參數成員函數Close可以關閉記錄集.在調用了Close函數後,程序可以再次調用Open建立新的記錄集.CRecordset的析構函數會調用Close函數,所以當刪除CRecordset對象時記錄集也隨之關閉。
10.5.5 滾動記錄
CRecordset提供了幾個成員函數用來在記錄集中滾動,如下所示.當用這些函數滾動到一個新記錄時,框架會自動地把新記錄的內容拷貝到域數據成員中.
void MoveNext( ); //前進一個記錄
void MovePrev( ); //後退一個記錄
void MoveFirst( ); //滾動到記錄集中的第一個記錄
void MoveLast( ); //滾動到記錄集中的最後一個記錄
void SetAbsolutePosition( long nRows );
該函數用於滾動到由參數nRows指定的絕對位置處.若nRows為負數,則從後往前滾動.例如,當nRows為-1時,函數就滾動到記錄集的末尾.注意,該函數不會跳過被刪除的記錄.
virtual void Move( long nRows, WORD wFetchType = SQL_FETCH_RELATIVE );
該函數功能強大.通過將wFetchType參數指定為SQL_FETCH_NEXT、SQL_FETCH_PRIOR、 SQL_FETCH_FIRST、SQL_FETCH_LAST和SQL_FETCH_ABSOLUTE,可以完成上面五個函數的功能.若 wFetchType為SQL_FETCH_RELATIVE,那麼將相對當前記錄移動,若nRows為正數,則向前移動,若nRows為負數,則向後移 動.
如果在建立記錄集時選擇了CRecordset::skipDeletedRecords選項,那麼除了SetAbsolutePosition外,在滾動記錄時將跳過被刪除的記錄,這一點對象FoxPro這樣的資料庫十分重要.
如果記錄集是空的,那麼調用上述函數將產生異常.另外,必須保證滾動沒有超出記錄集的邊界.調用IsEOF和IsBOF可以進行這方面的檢測.
BOOL IsEOF( ) const;
如果記錄集為空或滾動過了最後一個記錄,那麼函數返回TRUE,否則返回FALSE.
BOOL IsBOF( ) const;
如果記錄集為空或滾動過了第一個記錄,那麼函數返回TRUE,否則返回FALSE.
㈥ 在android中對資料庫做增刪改查有兩種方式分別是sqlitedatabase這個類中的哪幾個
一、使用嵌入式關系型SQLite資料庫存儲數據
在Android平台上,集成了一個嵌入式關系型資料庫——SQLite,SQLite3支持NULL、INTEGER、REAL(浮點數字)、 TEXT(字元串文本)和BLOB(二進制對象)數據類型,雖然它支持的類型只有五種,但實際上sqlite3也接受varchar(n)、 char(n)、decimal(p,s) 等數據類型,只不過在運算或保存時會轉成對應的五種數據類型。 SQLite最大的特點是你可以把各種類型的數據保存到任何欄位中,而不用關心欄位聲明的數據類型是什麼。例如:可以在Integer類型的欄位中存放字元串,或者在布爾型欄位中存放浮點數,或者在字元型欄位中存放日期型值。 但有一種情況例外:定義為INTEGER PRIMARY KEY的欄位只能存儲64位整數, 當向這種欄位保存除整數以外的數據時,將會產生錯誤。 另外,在編寫CREATE TABLE 語句時,你可以省略跟在欄位名稱後面的數據類型信息,如下面語句你可以省略name欄位的類型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分標准SQL語句,如:
復制代碼 代碼如下:
查詢語句:select * from 表名 where 條件子句 group by 分組字句 having ... order by 排序子句
如: select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分頁SQL與mysql類似,下面SQL語句獲取5條記錄,跳過前面3條記錄
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入語句:insert into 表名(欄位列表) values(值列表)。如: insert into person(name, age) values(『傳智',3)
更新語句:update 表名 set 欄位名=值 where 條件子句。如:update person set name=『傳智『 where id=10
刪除語句:delete from 表名 where 條件子句。如:delete from person where id=10
二、使用SQLiteOpenHelper對資料庫進行版本管理
我們在編寫資料庫應用軟體時,需要考慮這樣的問題:因為我們開發的軟體可能會安裝在很多用戶的手機上,如果應用使用到了SQLite資料庫,我們必須在用戶初次使用軟體時創建出應用使用到的資料庫表結構及添加一些初始化記錄,另外在軟體升級的時候,也需要對數據表結構進行更新。那麼,我們如何才能實現在用戶初次使用或升級軟體時自動在用戶的手機上創建出應用需要的資料庫表呢?總不能讓我們在每個需要安裝此軟體的手機上通過手工方式創建資料庫表吧?因為這種需求是每個資料庫應用都要面臨的,所以在Android系統,為我們提供了一個名為SQLiteOpenHelper的抽象類,必須繼承它才能使用,它是通過對資料庫版本進行管理來實現前面提出的需求。
為了實現對資料庫版本進行管理,SQLiteOpenHelper類提供了兩個重要的方法,分別是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用於初次使用軟體時生成資料庫表,後者用於升級軟體時更新資料庫表結構。當調用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法獲取用於操作資料庫的SQLiteDatabase實例的時候,如果資料庫不存在,Android系統會自動生成一個資料庫,接著調用onCreate()方法,onCreate()方法在初次生成資料庫時才會被調用,在onCreate()方法里可以生成資料庫表結構及添加一些應用使用到的初始化數據。onUpgrade()方法在資料庫的版本發生變化時會被調用,一般在軟體升級時才需改變版本號,而資料庫的版本是由程序員控制的,假設資料庫現在的版本是1,由於業務的變更,修改了資料庫表結構,這時候就需要升級軟體,升級軟體時希望更新用戶手機里的資料庫表結構,為了實現這一目的,可以把原來的資料庫版本設置為2(有同學問設置為3行不行?當然可以,如果你願意,設置為100也行),並且在 onUpgrade()方法裡面實現表結構的更新。當軟體的版本升級次數比較多,這時在onUpgrade()方法裡面可以根據原版號和目標版本號進行判斷,然後作出相應的表結構及數據更新。
getWritableDatabase()和 getReadableDatabase()方法都可以獲取一個用於操作資料庫的SQLiteDatabase實例。但 getWritableDatabase() 方法以讀寫方式打開資料庫,一旦資料庫的磁碟空間滿了,資料庫就只能讀而不能寫,倘若使用getWritableDatabase()打開資料庫就會出錯。getReadableDatabase()方法先以讀寫方式打開資料庫,如果資料庫的磁碟空間滿了,就會打開失敗,當打開失敗後會繼續嘗試以只讀方式打開資料庫。
注意:getWritableDatabase(),getReadableDatabase的區別是當資料庫寫滿時,調用前者會報錯,調用後者不會,所以如果不是更新資料庫的話,最好調用後者來獲得資料庫連接。
代碼:
復制代碼 代碼如下:
public class DatabaseHelper extends SQLiteOpenHelper {
//類沒有實例化,是不能用作父類構造器的參數,必須聲明為靜態
private static final String name = "ljqdb"; //資料庫名稱
private static final int version = 1; //資料庫版本
public DatabaseHelper(Context context) {
//第三個參數CursorFactory指定在執行查詢時獲得一個游標實例的工廠類,設置為null,代表使用系統默認的工廠類
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS person (
personid integer primary key autoincrement, name varchar(20), age INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(" ALTER TABLE person ADD phone VARCHAR(12) NULL "); //往表中增加一列
// DROP TABLE IF EXISTS person 刪除表
}
}
在實際項目開發中,當資料庫表結構發生更新時,應該避免用戶存放於資料庫中的數據丟失。
三、使用SQLiteDatabase操作SQLite資料庫
Android提供了一個名為SQLiteDatabase的類,該類封裝了一些操作資料庫的API,使用該類可以完成對數據進行添加(Create)、查詢(Retrieve)、更新(Update)和刪除(Delete)操作(這些操作簡稱為CRUD)。對SQLiteDatabase的學習,我們應該重點掌握execSQL()和rawQuery()方法。execSQL()方法可以執行insert、delete、update和CREATE TABLE之類有更改行為的SQL語句; rawQuery()方法用於執行select語句。
execSQL()方法的使用例子:
復制代碼 代碼如下:
SQLiteDatabase db = ....;
db.execSQL("insert into person(name, age) values('林計欽', 24)");
db.close();
執行上面SQL語句會往person表中添加進一條記錄,在實際應用中, 語句中的「林計欽」這些參數值會由用戶輸入界面提供,如果把用戶輸入的內容原樣組拼到上面的insert語句, 當用戶輸入的內容含有單引號時,組拼出來的SQL語句就會存在語法錯誤。要解決這個問題需要對單引號進行轉義,也就是把單引號轉換成兩個單引號。有些時候用戶往往還會輸入像「 & 」這些特殊SQL符號,為保證組拼好的SQL語句語法正確,必須對SQL語句中的這些特殊SQL符號都進行轉義,顯然,對每條SQL語句都做這樣的處理工作是比較煩瑣的。 SQLiteDatabase類提供了一個重載後的execSQL(String sql, Object[] bindArgs)方法,使用這個方法可以解決前面提到的問題,因為這個方法支持使用佔位符參數(?)。使用例子如下:
復制代碼 代碼如下:
SQLiteDatabase db = ....;
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"傳智播客", 4});
db.close();
execSQL(String sql, Object[] bindArgs)方法的第一個參數為SQL語句,第二個參數為SQL語句中佔位符參數的值,參數值在數組中的順序要和佔位符的位置對應。
SQLiteDatabase的rawQuery()用於執行select語句,使用例子如下:
復制代碼 代碼如下:
SQLiteDatabase db = ....;
Cursor cursor = db.rawQuery("select * from person", null);
while (cursor.moveToNext()) {
int personid = cursor.getInt(0); //獲取第一列的值,第一列的索引從0開始
String name = cursor.getString(1);//獲取第二列的值
int age = cursor.getInt(2);//獲取第三列的值
}
cursor.close();
db.close();
rawQuery()方法的第一個參數為select語句;第二個參數為select語句中佔位符參數的值,如果select語句沒有使用佔位符,該參數可以設置為null。帶佔位符參數的select語句使用例子如下:
復制代碼 代碼如下:
Cursor cursor = db.rawQuery("select * from person where name like ? and age=?", new String[]{"%林計欽%", "4"});
Cursor是結果集游標,用於對結果集進行隨機訪問,如果大家熟悉jdbc, 其實Cursor與JDBC中的ResultSet作用很相似。使用moveToNext()方法可以將游標從當前行移動到下一行,如果已經移過了結果集的最後一行,返回結果為false,否則為true。另外Cursor 還有常用的moveToPrevious()方法(用於將游標從當前行移動到上一行,如果已經移過了結果集的第一行,返回值為false,否則為true )、moveToFirst()方法(用於將游標移動到結果集的第一行,如果結果集為空,返回值為false,否則為true )和moveToLast()方法(用於將游標移動到結果集的最後一行,如果結果集為空,返回值為false,否則為true ) 。
除了前面給大家介紹的execSQL()和rawQuery()方法, SQLiteDatabase還專門提供了對應於添加、刪除、更新、查詢的操作方法: insert()、delete()、update()和query() 。這些方法實際上是給那些不太了解SQL語法的菜鳥使用的,對於熟悉SQL語法的程序員而言,直接使用execSQL()和rawQuery()方法執行SQL語句就能完成數據的添加、刪除、更新、查詢操作。
㈦ C#中如何定義資料庫操作類,並調用
以下是我編寫的一個操作access資料庫的類,其他資料庫可以參考修改,原理差不多的。希望對你有幫助。
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;
using System.Configuration;
using System.Data;
namespace AutoEmailSender
{
/// <summary>
/// 資料庫交互類
/// </summary>
public class DB
{
/// <summary>
/// 獲得資料庫連接
/// </summary>
/// <returns></returns>
public static OleDbConnection GetDBConnection()
{
return new OleDbConnection(ConfigurationManager.AppSettings["ConnectString"]);
}
/// <summary>
/// 查詢結果集
/// </summary>
/// <param name="sql">執行語句</param>
/// <returns>返回一個DataTable對象</returns>
public static DataTable ExecuteDataTable(string sql)
{
using (OleDbConnection con = GetDBConnection())
{
OleDbCommand cmd = new OleDbCommand(sql, con);
return ExecuteDataTable(cmd);
}
}
/// <summary>
/// 查詢結果集
/// </summary>
/// <param name="cmd">執行語句的OleDbCommand命令</param>
/// <returns>返回一個DataTable對象</returns>
public static DataTable ExecuteDataTable(OleDbCommand cmd)
{
DataSet ds = new DataSet();
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
try
{
da.Fill(ds);
}
catch (Exception e)
{
throw e;
}
}
if (ds.Tables.Count > 0)
{
ds.Tables[0].DefaultView.RowStateFilter = DataViewRowState.Unchanged | DataViewRowState.Added | DataViewRowState.ModifiedCurrent | DataViewRowState.Deleted;
return ds.Tables[0];
}
else
return null;
}
/// <summary>
/// 執行查詢,並返回查詢所返回的結果集中第一行的第一列。忽略其他列或行。
/// </summary>
/// <param name="sql">查詢語句</param>
/// <returns>返回結果集中第一行的第一列的object值</returns>
public static object ExecuteScalar(string sql)
{
using (OleDbConnection con = GetDBConnection())
{
OleDbCommand cmd = new OleDbCommand(sql, con);
return ExecuteScalar(cmd);
}
}
/// <summary>
/// 執行查詢,並返回查詢所返回的結果集中第一行的第一列。忽略其他列或行。
/// </summary>
/// <param name="cmd">查詢命令</param>
/// <returns>返回結果集中第一行的第一列的object值</returns>
public static object ExecuteScalar(OleDbCommand cmd)
{
try
{
cmd.Connection.Open();
object obj = cmd.ExecuteScalar();
cmd.Connection.Close();
return obj;
}
catch (Exception error)
{
cmd.Connection.Close();
throw error;
}
}
/// <summary>
/// 更新數據集
/// </summary>
/// <param name="dt">要更新的數據集</param>
/// <param name="insertCmd">插入SQL語句</param>
/// <param name="updateCmd">更新SQL語句</param>
/// <param name="deleteCmd">刪除SQL語句</param>
/// <returns></returns>
public static int UpdateDataSet(DataTable dt, OleDbCommand insertCmd, OleDbCommand updateCmd, OleDbCommand deleteCmd)
{
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.InsertCommand = insertCmd;
da.UpdateCommand = updateCmd;
da.DeleteCommand = deleteCmd;
//da.UpdateBatchSize = 0; //UpdateBatchSize:指定可在一次批處理中執行的命令的數量,在Access不被支持。0:批大小沒有限制。1:禁用批量更新。>1:更改是使用 UpdateBatchSize 操作的批處理一次性發送的。
da.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
da.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
da.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
try
{
int row = da.Update(dt);
return row;
}
catch (Exception e)
{
throw e;
}
}
}
/// <summary>
/// 返回一個查詢語句執行結果的表結構
/// </summary>
/// <param name="sql">查詢語句,不支持復雜SQL</param>
/// <returns></returns>
public static DataTable GetTableSchema(string sql)
{
sql = sql.ToUpper();
DataTable dt = null;
using (OleDbConnection con = GetDBConnection())
{
OleDbCommand cmd = new OleDbCommand(sql, con);
con.Open();
using (OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly | CommandBehavior.CloseConnection))
{
dt = dr.GetSchemaTable();
}
}
return dt;
}
/// <summary>
/// 根據輸入的查詢語句自動生成插入,更新,刪除命令
/// </summary>
/// <param name="sql">查詢語句</param>
/// <param name="insertCmd">插入命令</param>
/// <param name="updateCmd">更新命令</param>
/// <param name="deleteCmd">刪除命令</param>
public static void GenerateUpdateSQL(string sql, OleDbCommand insertCmd, OleDbCommand updateCmd, OleDbCommand deleteCmd)
{
sql = sql.ToUpper();
DataTable dt = GetTableSchema(sql);
string tableName = dt.Rows[0]["BaseTableName"].ToString();
List<OleDbParameter> updatePrimarykeys = new List<OleDbParameter>();//主鍵參數集合
List<OleDbParameter> deletePrimarykeys = new List<OleDbParameter>();//主鍵參數集合,因為不能同時被OleDbCommand個命令引用,所以多申明一個
List<OleDbParameter> insertFields = new List<OleDbParameter>();//欄位參數集合
List<OleDbParameter> updateFields = new List<OleDbParameter>();//欄位參數集合
string columns = string.Empty, values = "", set = "", where = "";
foreach (DataRow dr in dt.Rows)
{
if (dr["IsAutoIncrement"].ToString().Equals("False"))
{
insertFields.Add(new OleDbParameter("@" + dr["BaseColumnName"].ToString(),
(OleDbType)dr["ProviderType"],
Convert.ToInt32(dr["ColumnSize"]),
dr["BaseColumnName"].ToString()));
updateFields.Add(new OleDbParameter("@" + dr["BaseColumnName"].ToString(),
(OleDbType)dr["ProviderType"],
Convert.ToInt32(dr["ColumnSize"]),
dr["BaseColumnName"].ToString()));
if (!string.IsNullOrEmpty(columns))
columns += ",";
columns += dr["BaseColumnName"].ToString();
if (!string.IsNullOrEmpty(values))
values += ",";
values += "@" + dr["BaseColumnName"].ToString();
if (!string.IsNullOrEmpty(set))
set += ",";
set += dr["BaseColumnName"].ToString() + "=@" + dr["BaseColumnName"].ToString();
}
if (dr["IsKey"].ToString().Equals("True"))
{
updatePrimarykeys.Add(new OleDbParameter("@OLD_" + dr["BaseColumnName"].ToString(),
(OleDbType)dr["ProviderType"],
Convert.ToInt32(dr["ColumnSize"]),
ParameterDirection.Input,
Convert.ToBoolean(dr["AllowDBNull"]),
Convert.ToByte(dr["NumericScale"]),
Convert.ToByte(dr["NumericPrecision"]),
dr["BaseColumnName"].ToString(), DataRowVersion.Original, null));
deletePrimarykeys.Add(new OleDbParameter("@OLD_" + dr["BaseColumnName"].ToString(),
(OleDbType)dr["ProviderType"],
Convert.ToInt32(dr["ColumnSize"]),
ParameterDirection.Input,
Convert.ToBoolean(dr["AllowDBNull"]),
Convert.ToByte(dr["NumericScale"]),
Convert.ToByte(dr["NumericPrecision"]),
dr["BaseColumnName"].ToString(), DataRowVersion.Original, null));
if (!string.IsNullOrEmpty(where))
where += " and ";
where += dr["BaseColumnName"].ToString() + "=@OLD_" + dr["BaseColumnName"].ToString();
}
}
insertCmd.CommandText = string.Format("insert into {0} ({1}) values ({2})", tableName, columns, values);
updateCmd.CommandText = string.Format("update {0} set {1} where {2}", tableName, set, where);
deleteCmd.CommandText = string.Format("delete from {0} where {1}", tableName, where);
insertCmd.Connection = GetDBConnection();
updateCmd.Connection = GetDBConnection();
deleteCmd.Connection = GetDBConnection();
foreach (OleDbParameter pa in insertFields)
{
insertCmd.Parameters.Add(pa);
}
foreach (OleDbParameter pa in updateFields)
{
updateCmd.Parameters.Add(pa);
}
foreach (OleDbParameter pa in updatePrimarykeys)
{
updateCmd.Parameters.Add(pa);
}
foreach (OleDbParameter pa in deletePrimarykeys)
{
deleteCmd.Parameters.Add(pa);
}
}
}
}
㈧ c#.net關於資料庫操作的類
1.這僅僅是一個聲明了一個資料庫的連接字元串。它只是告訴你要使用的資料庫在什麼位置以及我們使用何種身份去連接資料庫。要實際的連接資料庫的操作還需要你去創建SqlConnection對象,之後調用Open方法,這樣才真正的連接到了資料庫。
2.以後你使用DBBase這個類去操作資料庫時都會採用connectionString 這個連接字元串。
㈨ 如何進行Android資料庫操作
Android資料庫操作類實例
實體類:UserInfo.java
package my.db;
import java.io.Serializable;
import android.graphics.drawable.Drawable;
public class UserInfo implements Serializable {
public static final String ID = "_id";
public static final String USERID = "userId";
public static final String TOKEN = "token";
public static final String TOKENSECRET = "tokenSecret";
public static final String USERNAME = "userName";
public static final String USERICON = "userIcon";
private String id;
private String userId; // 用戶id
private String token;
private String tokenSecret;
private String userName;
private Drawable userIcon;
//getter and setter省略
}
SqliteHelper類:
package my.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class SqliteHelper extends SQLiteOpenHelper{
//用來保存UserID、Access Token、Access Secret的表名
public static final String TB_NAME= "users";
public SqliteHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
//創建表
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL( "CREATE TABLE IF NOT EXISTS "+
TB_NAME+ "("+
UserInfo. ID+ " integer primary key,"+
UserInfo. USERID+ " varchar,"+
UserInfo. TOKEN+ " varchar,"+
UserInfo. TOKENSECRET+ " varchar,"+
UserInfo. USERNAME+ " varchar,"+
UserInfo. USERICON+ " blob"+
")"
);
Log. e("Database" ,"onCreate" );
}
//更新表
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL( "DROP TABLE IF EXISTS " + TB_NAME );
onCreate(db);
Log. e("Database" ,"onUpgrade" );
}
//更新列
public void updateColumn(SQLiteDatabase db, String oldColumn, String newColumn, String typeColumn){
try{
db.execSQL( "ALTER TABLE " +
TB_NAME + " CHANGE " +
oldColumn + " "+ newColumn +
" " + typeColumn
);
} catch(Exception e){
e.printStackTrace();
}
}
}
CRUD類DataHelper:
package my.db;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
public class DataHelper {
// 資料庫名稱
private static String DB_NAME = "weibo.db";
// 資料庫版本
private static int DB_VERSION = 2;
private SQLiteDatabase db;
private SqliteHelper dbHelper;
public DataHelper(Context context) {
dbHelper = new SqliteHelper(context, DB_NAME, null, DB_VERSION );
db = dbHelper.getWritableDatabase();
}
public void Close() {
db.close();
dbHelper.close();
}
// 獲取users表中的UserID、Access Token、Access Secret的記錄
public List<UserInfo> GetUserList(Boolean isSimple) {
List<UserInfo> userList = new ArrayList<UserInfo>();
Cursor cursor = db.query(SqliteHelper. TB_NAME, null, null , null, null,
null, UserInfo. ID + " DESC");
cursor.moveToFirst();
while (!cursor.isAfterLast() && (cursor.getString(1) != null )) {
UserInfo user = new UserInfo();
user.setId(cursor.getString(0));
user.setUserId(cursor.getString(1));
user.setToken(cursor.getString(2));
user.setTokenSecret(cursor.getString(3));
if (!isSimple) {
user.setUserName(cursor.getString(4));
ByteArrayInputStream stream = new ByteArrayInputStream(cursor.getBlob(5));
Drawable icon = Drawable.createFromStream(stream, "image");
user.setUserIcon(icon);
}
userList.add(user);
cursor.moveToNext();
}
cursor.close();
return userList;
}
// 判斷users表中的是否包含某個UserID的記錄
public Boolean HaveUserInfo(String UserId) {
Boolean b = false;
Cursor cursor = db.query(SqliteHelper. TB_NAME, null, UserInfo.USERID
+ "=?", new String[]{UserId}, null, null, null );
b = cursor.moveToFirst();
Log. e("HaveUserInfo", b.toString());
cursor.close();
return b;
}
// 更新users表的記錄,根據UserId更新用戶昵稱和用戶圖標
public int UpdateUserInfo(String userName, Bitmap userIcon, String UserId) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERNAME, userName);
// BLOB類型
final ByteArrayOutputStream os = new ByteArrayOutputStream();
// 將Bitmap壓縮成PNG編碼,質量為100%存儲
userIcon.compress(Bitmap.CompressFormat. PNG, 100, os);
// 構造SQLite的Content對象,這里也可以使用raw
values.put(UserInfo. USERICON, os.toByteArray());
int id = db.update(SqliteHelper. TB_NAME, values, UserInfo.USERID + "=?" , new String[]{UserId});
Log. e("UpdateUserInfo2", id + "");
return id;
}
// 更新users表的記錄
public int UpdateUserInfo(UserInfo user) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
int id = db.update(SqliteHelper. TB_NAME, values, UserInfo.USERID + "="
+ user.getUserId(), null);
Log. e("UpdateUserInfo", id + "");
return id;
}
// 添加users表的記錄
public Long SaveUserInfo(UserInfo user) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
Long uid = db.insert(SqliteHelper. TB_NAME, UserInfo.ID, values);
Log. e("SaveUserInfo", uid + "");
return uid;
}
// 添加users表的記錄
public Long SaveUserInfo(UserInfo user, byte[] icon) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. USERNAME, user.getUserName());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
if(icon!= null){
values.put(UserInfo. USERICON, icon);
}
Long uid = db.insert(SqliteHelper. TB_NAME, UserInfo.ID, values);
Log. e("SaveUserInfo", uid + "");
return uid;
}
// 刪除users表的記錄
public int DelUserInfo(String UserId) {
int id = db.delete(SqliteHelper. TB_NAME,
UserInfo. USERID + "=?", new String[]{UserId});
Log. e("DelUserInfo", id + "");
return id;
}
public static UserInfo getUserByName(String userName,List<UserInfo> userList){
UserInfo userInfo = null;
int size = userList.size();
for( int i=0;i<size;i++){
if(userName.equals(userList.get(i).getUserName())){
userInfo = userList.get(i);
break;
}
}
return userInfo;
}
}
㈩ 資料庫分為哪幾類
常用資料庫
1. IBM 的DB2
作為關系資料庫領域的開拓者和領航人,IBM在1997年完成了System R系統的原型,1980年開始提供集成的資料庫伺服器—— System/38,隨後是SQL/DSforVSE和VM,其初始版本與SystemR研究原型密切相關。DB2 forMVSV1 在1983年推出。該版本的目標是提供這一新方案所承諾的簡單性,數據不相關性和用戶生產率。1988年DB2 for MVS 提供了強大的在線事務處理(OLTP)支持,1989 年和1993 年分別以遠程工作單元和分布式工作單元實現了分布式資料庫支持。最近推出的DB2 Universal Database 6.1則是通用資料庫的典範,是第一個具備網上功能的多媒體關系資料庫管理系統,支持包括Linux在內的一系列平台。
2. Oracle
Oracle 前身叫SDL,由Larry Ellison 和另兩個編程人員在1977創辦,他們開發了自己的拳頭產品,在市場上大量銷售,1979 年,Oracle公司引入了第一個商用SQL 關系資料庫管理系統。Oracle公司是最早開發關系資料庫的廠商之一,其產品支持最廣泛的操作系統平台。目前Oracle關系資料庫產品的市場佔有率名列前茅。
3. Informix
Informix在1980年成立,目的是為Unix等開放操作系統提供專業的關系型資料庫產品。公司的名稱Informix便是取自Information 和Unix的結合。Informix第一個真正支持SQL語言的關系資料庫產品是Informix SE(StandardEngine)。InformixSE是在當時的微機Unix環境下主要的資料庫產品。它也是第一個被移植到Linux上的商業資料庫產品。
4. Sybase
Sybase公司成立於1984年,公司名稱「Sybase」取自「system」和 「database」 相結合的含義。Sybase公司的創始人之一Bob Epstein 是Ingres 大學版(與System/R同時期的關系資料庫模型產品)的主要設計人員。公司的第一個關系資料庫產品是1987年5月推出的Sybase SQLServer1.0。Sybase首先提出Client/Server 資料庫體系結構的思想,並率先在Sybase SQLServer 中實現。
5. SQL Server
1987 年,微軟和 IBM合作開發完成OS/2,IBM 在其銷售的OS/2 ExtendedEdition 系統中綁定了OS/2Database Manager,而微軟產品線中尚缺少資料庫產品。為此,微軟將目光投向Sybase,同Sybase 簽訂了合作協議,使用Sybase的技術開發基於OS/2平台的關系型資料庫。1989年,微軟發布了SQL Server 1.0 版。
6. PostgreSQL
PostgreSQL 是一種特性非常齊全的自由軟體的對象——關系性資料庫管理系統(ORDBMS),它的很多特性是當今許多商業資料庫的前身。PostgreSQL最早開始於BSD的Ingres項目。PostgreSQL 的特性覆蓋了SQL-2/SQL-92和SQL-3。首先,它包括了可以說是目前世界上最豐富的數據類型的支持;其次,目前PostgreSQL 是唯一支持事務、子查詢、多版本並行控制系統、數據完整性檢查等特性的唯一的一種自由軟體的資料庫管理系統.
7.mySQL
mySQL是一個小型關系型資料庫管理系統,開發者為瑞典MySQL AB公司。在2008年1月16號被Sun公司收購。目前MySQL被廣泛地應用在Internet上的中小型網站中。由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,許多中小型網站為了降低網站總體擁有成本而選擇了MySQL作為網站資料庫。MySQL的官方網站的網址是: www.mysql.com