SQLite là một hệ quản trị cơ sở dữ liệu (CSDL) quan hệ nhỏ gọn, được nhúng trực tiếp vào ứng dụng, và PHP là một ngôn ngữ lập trình kịch bản phía máy chủ phổ biến. Vậy, Sqlite Trong Php Hoạt động Ra Sao? Bài viết này sẽ cung cấp cho bạn một cái nhìn toàn diện về cách tích hợp và sử dụng SQLite trong các ứng dụng PHP, từ cơ bản đến nâng cao.
SQLite Là Gì và Tại Sao Nên Sử Dụng Nó với PHP?
SQLite là một thư viện C cung cấp một hệ thống quản lý cơ sở dữ liệu quan hệ (RDBMS) độc lập, không máy chủ, không cấu hình và giao dịch đầy đủ. Điều này có nghĩa là, không giống như các hệ thống cơ sở dữ liệu như MySQL hoặc PostgreSQL, bạn không cần một quy trình máy chủ riêng biệt để SQLite hoạt động. Toàn bộ cơ sở dữ liệu được lưu trữ trong một tệp duy nhất trên đĩa.
Ưu điểm của SQLite khi sử dụng với PHP:
- Đơn giản: Dễ cài đặt và sử dụng. Không cần cấu hình phức tạp, chỉ cần một tệp duy nhất.
- Nhẹ nhàng: Chiếm ít tài nguyên hệ thống, lý tưởng cho các ứng dụng nhỏ và vừa.
- Di động: Cơ sở dữ liệu là một tệp duy nhất, dễ dàng sao chép và di chuyển.
- Không máy chủ: Không cần máy chủ cơ sở dữ liệu riêng biệt, giảm chi phí quản lý và vận hành.
- Hoạt động tốt với PHP: PHP có hỗ trợ tích hợp cho SQLite, giúp việc phát triển ứng dụng dễ dàng hơn.
“SQLite là lựa chọn tuyệt vời cho các dự án PHP nhỏ đến trung bình, đặc biệt khi bạn cần một giải pháp cơ sở dữ liệu đơn giản, di động và không đòi hỏi nhiều tài nguyên,” theo anh Nguyễn Hoàng Nam, chuyên gia phát triển web tại TechSolutions Việt Nam.
Khi Nào Nên Sử Dụng SQLite với PHP?
SQLite đặc biệt phù hợp cho các trường hợp sau:
- Ứng dụng web nhỏ và vừa: Ví dụ: blog cá nhân, trang web giới thiệu sản phẩm, hệ thống quản lý nội dung đơn giản (CMS).
- Nguyên mẫu (Prototype) và phát triển nhanh: SQLite cho phép bạn nhanh chóng thiết lập và thử nghiệm cơ sở dữ liệu mà không cần cấu hình phức tạp.
- Ứng dụng độc lập: Ứng dụng desktop viết bằng PHP sử dụng SQLite để lưu trữ dữ liệu cục bộ.
- Ứng dụng nhúng: Ứng dụng chạy trên các thiết bị di động hoặc thiết bị IoT (Internet of Things) với tài nguyên hạn chế.
- Kiểm thử: Sử dụng SQLite làm cơ sở dữ liệu kiểm thử để đảm bảo tính nhất quán và dễ dàng thiết lập.
Khi Nào Không Nên Sử Dụng SQLite với PHP?
Mặc dù SQLite có nhiều ưu điểm, nó không phải là giải pháp phù hợp cho mọi trường hợp. Hãy cân nhắc sử dụng các hệ quản trị cơ sở dữ liệu khác như MySQL hoặc PostgreSQL nếu bạn cần:
- Khả năng mở rộng cao: SQLite không được thiết kế để xử lý lượng lớn dữ liệu và số lượng lớn người dùng đồng thời.
- Độ tin cậy cao: Trong môi trường có yêu cầu về độ tin cậy cao, các hệ quản trị cơ sở dữ liệu mạnh mẽ hơn có thể phù hợp hơn.
- Kiểm soát truy cập chi tiết: SQLite có giới hạn về khả năng kiểm soát truy cập và phân quyền so với các hệ quản trị cơ sở dữ liệu khác. Bạn có thể tìm hiểu thêm về phân quyền truy cập sqlite.
- Tính năng phức tạp: Nếu bạn cần các tính năng nâng cao như stored procedures, triggers, hoặc materialized views, SQLite có thể không đáp ứng được.
Cách Cài Đặt và Cấu Hình SQLite cho PHP
Việc cài đặt và cấu hình SQLite cho PHP khá đơn giản, đặc biệt là trên các hệ thống Linux. Hầu hết các bản phân phối Linux hiện đại đều đã cài đặt sẵn SQLite. Tuy nhiên, bạn cần đảm bảo rằng PHP đã được cấu hình để hỗ trợ SQLite.
Kiểm tra xem PHP đã hỗ trợ SQLite chưa:
Tạo một tệp PHP có tên info.php
với nội dung sau:
<?php
phpinfo();
?>
Mở tệp này trong trình duyệt web của bạn. Tìm kiếm “SQLite” trên trang. Nếu bạn thấy thông tin về SQLite3, điều đó có nghĩa là PHP của bạn đã hỗ trợ SQLite.
Cài đặt SQLite extension cho PHP (nếu chưa có):
Nếu bạn không thấy thông tin về SQLite, bạn cần cài đặt extension SQLite cho PHP. Cách thực hiện tùy thuộc vào hệ điều hành và cách bạn cài đặt PHP.
Trên Ubuntu/Debian:
sudo apt-get update
sudo apt-get install php-sqlite3
sudo systemctl restart apache2 # Hoặc nginx, tùy thuộc vào web server bạn đang sử dụng
Trên CentOS/RHEL:
sudo yum install php-sqlite3
sudo systemctl restart httpd # Hoặc nginx, tùy thuộc vào web server bạn đang sử dụng
Trên Windows:
Bạn cần tải xuống phiên bản DLL phù hợp với phiên bản PHP của bạn từ trang web PHP và đặt nó trong thư mục ext
của PHP. Sau đó, chỉnh sửa tệp php.ini
để bật extension bằng cách thêm dòng sau:
extension=sqlite3
Khởi động lại web server của bạn để các thay đổi có hiệu lực.
Xác minh cài đặt:
Sau khi cài đặt extension, hãy kiểm tra lại tệp info.php
để đảm bảo rằng SQLite3 đã được bật.
Cách Sử Dụng SQLite trong PHP: Các Bước Cơ Bản
Sau khi cài đặt và cấu hình xong, bạn đã sẵn sàng để bắt đầu sử dụng SQLite trong PHP. Dưới đây là các bước cơ bản:
- Kết nối đến cơ sở dữ liệu: Sử dụng hàm
SQLite3
để tạo một kết nối đến tệp cơ sở dữ liệu. - Thực hiện truy vấn: Sử dụng hàm
query
để thực hiện các câu lệnh SQL. - Lấy dữ liệu: Sử dụng các hàm như
fetchArray
để lấy dữ liệu từ kết quả truy vấn. - Đóng kết nối: Sử dụng hàm
close
để đóng kết nối đến cơ sở dữ liệu.
Ví dụ: Kết nối đến cơ sở dữ liệu và tạo bảng
<?php
class MyDB extends SQLite3 {
function __construct() {
$this->open('test.db');
}
}
$db = new MyDB();
if(!$db){
echo $db->lastErrorMsg();
} else {
echo "Opened database successfullyn";
}
$sql =<<<EOF
CREATE TABLE COMPANY
(ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL);
EOF;
$ret = $db->exec($sql);
if(!$ret){
echo $db->lastErrorMsg();
} else {
echo "Table created successfullyn";
}
$db->close();
?>
Đoạn code trên tạo một kết nối đến cơ sở dữ liệu test.db
(nếu tệp này chưa tồn tại, nó sẽ được tạo). Sau đó, nó tạo một bảng có tên COMPANY
với các cột ID
, NAME
, AGE
, ADDRESS
, và SALARY
.
Ví dụ: Thêm dữ liệu vào bảng
<?php
class MyDB extends SQLite3 {
function __construct() {
$this->open('test.db');
}
}
$db = new MyDB();
if(!$db){
echo $db->lastErrorMsg();
} else {
echo "Opened database successfullyn";
}
$sql =<<<EOF
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );
EOF;
$ret = $db->exec($sql);
if(!$ret){
echo $db->lastErrorMsg();
} else {
echo "Records created successfullyn";
}
$db->close();
?>
Đoạn code này thêm bốn bản ghi vào bảng COMPANY
.
Ví dụ: Truy vấn dữ liệu từ bảng
<?php
class MyDB extends SQLite3 {
function __construct() {
$this->open('test.db');
}
}
$db = new MyDB();
if(!$db){
echo $db->lastErrorMsg();
} else {
echo "Opened database successfullyn";
}
$sql =<<<EOF
SELECT * from COMPANY;
EOF;
$ret = $db->query($sql);
while($row = $ret->fetchArray(SQLITE3_ASSOC) ){
echo "ID = ". $row['ID'] . "n";
echo "NAME = ". $row['NAME'] ."n";
echo "AGE = ". $row['AGE'] ."n";
echo "ADDRESS = ". $row['ADDRESS'] ."n";
echo "SALARY = ".$row['SALARY'] ."nn";
}
$db->close();
?>
Đoạn code này truy vấn tất cả các bản ghi từ bảng COMPANY
và in chúng ra màn hình.
Các Phương Pháp Kết Nối SQLite Trong PHP
PHP cung cấp một vài cách để kết nối và tương tác với cơ sở dữ liệu SQLite. Dưới đây là ba phương pháp phổ biến nhất:
- SQLite3 Class: Đây là phương pháp hướng đối tượng, cung cấp một giao diện rõ ràng và dễ sử dụng.
- PDO (PHP Data Objects): PDO là một lớp trừu tượng hóa cơ sở dữ liệu, cho phép bạn làm việc với nhiều loại cơ sở dữ liệu khác nhau (bao gồm SQLite) bằng cùng một giao diện.
- SQLite Functions (deprecated): Đây là một tập hợp các hàm thủ tục, nhưng nó đã bị deprecated (không khuyến khích sử dụng) và có thể bị loại bỏ trong các phiên bản PHP tương lai.
SQLite3 Class
Như đã thấy trong các ví dụ trước, SQLite3
class cung cấp một cách trực quan để làm việc với SQLite. Bạn tạo một đối tượng SQLite3
, mở kết nối đến cơ sở dữ liệu, thực hiện các truy vấn, và sau đó đóng kết nối.
<?php
$db = new SQLite3('mydatabase.db');
$results = $db->query('SELECT * FROM mytable');
while ($row = $results->fetchArray()) {
echo $row['column1'] . ' ' . $row['column2'] . '<br>';
}
$db->close();
?>
PDO (PHP Data Objects)
PDO cung cấp một lớp trừu tượng hóa cơ sở dữ liệu mạnh mẽ và linh hoạt. Nó cho phép bạn chuyển đổi giữa các loại cơ sở dữ liệu khác nhau mà không cần thay đổi nhiều mã.
<?php
try {
$db = new PDO('sqlite:mydatabase.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare('SELECT * FROM mytable');
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['column1'] . ' ' . $row['column2'] . '<br>';
}
$db = null; // Đóng kết nối
} catch (PDOException $e) {
echo "Lỗi kết nối: " . $e->getMessage();
}
?>
Sử dụng PDO mang lại lợi ích lớn về tính linh hoạt và khả năng bảo trì, đặc biệt khi bạn có thể cần chuyển đổi sang một hệ quản trị cơ sở dữ liệu khác trong tương lai.
So Sánh Giữa SQLite3 Class và PDO
Tính năng | SQLite3 Class | PDO |
---|---|---|
Giao diện | Hướng đối tượng | Hướng đối tượng |
Tính linh hoạt | Chỉ hỗ trợ SQLite | Hỗ trợ nhiều loại cơ sở dữ liệu khác nhau |
Bảo mật | Cần tự xử lý các vấn đề bảo mật | Cung cấp các tính năng bảo mật như prepared statements |
Hiệu suất | Có thể nhanh hơn trong một số trường hợp cụ thể | Có thể chậm hơn một chút do lớp trừu tượng hóa |
Theo chuyên gia bảo mật Phạm Thị Mai Anh, “Sử dụng prepared statements với PDO là một cách tuyệt vời để ngăn chặn các cuộc tấn công SQL injection, đặc biệt quan trọng trong các ứng dụng web có tương tác với người dùng.”
Các Thao Tác CRUD với SQLite trong PHP
CRUD là viết tắt của Create, Read, Update, và Delete, là bốn thao tác cơ bản mà bạn thường thực hiện với một cơ sở dữ liệu.
Create (Tạo)
Tạo một bản ghi mới trong bảng.
<?php
$db = new SQLite3('mydatabase.db');
$name = 'New Record';
$age = 30;
$stmt = $db->prepare('INSERT INTO mytable (name, age) VALUES (:name, :age)');
$stmt->bindValue(':name', $name, SQLITE3_TEXT);
$stmt->bindValue(':age', $age, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
echo "Bản ghi đã được tạo thành công.";
} else {
echo "Lỗi khi tạo bản ghi: " . $db->lastErrorMsg();
}
$db->close();
?>
Read (Đọc)
Lấy dữ liệu từ bảng.
<?php
$db = new SQLite3('mydatabase.db');
$id = 1; // Lấy bản ghi có ID là 1
$stmt = $db->prepare('SELECT * FROM mytable WHERE id = :id');
$stmt->bindValue(':id', $id, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray();
if ($row) {
echo "Name: " . $row['name'] . "<br>";
echo "Age: " . $row['age'] . "<br>";
} else {
echo "Không tìm thấy bản ghi nào với ID là " . $id;
}
$db->close();
?>
Update (Cập nhật)
Cập nhật dữ liệu của một bản ghi hiện có trong bảng.
<?php
$db = new SQLite3('mydatabase.db');
$id = 1;
$newName = 'Updated Name';
$newAge = 35;
$stmt = $db->prepare('UPDATE mytable SET name = :name, age = :age WHERE id = :id');
$stmt->bindValue(':name', $newName, SQLITE3_TEXT);
$stmt->bindValue(':age', $newAge, SQLITE3_INTEGER);
$stmt->bindValue(':id', $id, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
echo "Bản ghi đã được cập nhật thành công.";
} else {
echo "Lỗi khi cập nhật bản ghi: " . $db->lastErrorMsg();
}
$db->close();
?>
Delete (Xóa)
Xóa một bản ghi khỏi bảng.
<?php
$db = new SQLite3('mydatabase.db');
$id = 1;
$stmt = $db->prepare('DELETE FROM mytable WHERE id = :id');
$stmt->bindValue(':id', $id, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
echo "Bản ghi đã được xóa thành công.";
} else {
echo "Lỗi khi xóa bản ghi: " . $db->lastErrorMsg();
}
$db->close();
?>
Các Vấn Đề Thường Gặp và Cách Xử Lý Khi Sử Dụng SQLite với PHP
Khi làm việc với SQLite và PHP, bạn có thể gặp phải một số vấn đề. Dưới đây là một vài vấn đề thường gặp và cách giải quyết:
- Không thể mở cơ sở dữ liệu: Đảm bảo rằng tệp cơ sở dữ liệu tồn tại và PHP có quyền đọc và ghi vào tệp đó.
- SQLite extension không được bật: Kiểm tra lại tệp
php.ini
để đảm bảo rằng extension SQLite đã được bật và khởi động lại web server. - Lỗi SQL syntax: Kiểm tra kỹ câu lệnh SQL của bạn để đảm bảo rằng nó đúng cú pháp.
- Vấn đề về encoding: Đảm bảo rằng bạn đang sử dụng cùng một encoding (ví dụ: UTF-8) cho cơ sở dữ liệu, PHP, và HTML.
- Hiệu suất chậm: Nếu bạn đang làm việc với một lượng lớn dữ liệu, hãy cân nhắc sử dụng indexes để tăng tốc độ truy vấn.
- Khóa cơ sở dữ liệu: SQLite sử dụng khóa tệp để đồng bộ hóa. Nếu một quá trình đang viết vào cơ sở dữ liệu, các quá trình khác có thể bị khóa cho đến khi quá trình đầu tiên hoàn thành. Trong các ứng dụng web có nhiều người dùng đồng thời, điều này có thể gây ra vấn đề. Cân nhắc sử dụng một hệ quản trị cơ sở dữ liệu khác nếu bạn cần xử lý nhiều truy cập đồng thời. Bạn có thể tìm hiểu thêm về sqlite có dùng được cho website không.
Tối Ưu Hiệu Năng Khi Sử Dụng SQLite Trong PHP
Để đảm bảo ứng dụng PHP của bạn hoạt động hiệu quả khi sử dụng SQLite, hãy xem xét các mẹo sau:
- Sử dụng Indexes: Indexes giúp tăng tốc độ truy vấn bằng cách cho phép SQLite nhanh chóng tìm thấy các bản ghi phù hợp mà không cần quét toàn bộ bảng.
- Sử dụng Prepared Statements: Prepared statements giúp tăng hiệu suất bằng cách biên dịch câu lệnh SQL một lần và sau đó thực hiện nó nhiều lần với các tham số khác nhau. Điều này đặc biệt hữu ích cho các truy vấn lặp đi lặp lại.
- Transaction: Sử dụng transactions để nhóm nhiều thao tác cơ sở dữ liệu thành một đơn vị duy nhất. Nếu một thao tác thất bại, tất cả các thao tác khác sẽ được hoàn tác, đảm bảo tính nhất quán của dữ liệu.
- Hạn chế số lượng truy vấn: Cố gắng giảm thiểu số lượng truy vấn bạn thực hiện. Ví dụ, thay vì thực hiện nhiều truy vấn nhỏ, hãy thử thực hiện một truy vấn lớn hơn để lấy tất cả dữ liệu bạn cần cùng một lúc.
- Tối ưu hóa cấu trúc cơ sở dữ liệu: Thiết kế cấu trúc cơ sở dữ liệu của bạn một cách hiệu quả. Chọn kiểu dữ liệu phù hợp cho mỗi cột và tránh sử dụng các kiểu dữ liệu lớn hơn mức cần thiết.
- Sử dụng caching: Sử dụng caching để lưu trữ kết quả của các truy vấn thường xuyên được sử dụng. Điều này có thể giúp giảm tải cho cơ sở dữ liệu và tăng tốc độ phản hồi của ứng dụng.
- Phân tích truy vấn: Sử dụng công cụ phân tích truy vấn của SQLite để xác định các truy vấn chậm và tìm cách tối ưu hóa chúng.
- Kiểm tra và tối ưu hóa code PHP: Đảm bảo rằng code PHP của bạn được viết hiệu quả và không gây ra bất kỳ tắc nghẽn nào.
SQLite và JSON trong PHP
SQLite có thể lưu trữ dữ liệu JSON, nhưng nó không có các hàm tích hợp sẵn để thao tác với JSON như một số hệ quản trị cơ sở dữ liệu khác (ví dụ: MySQL 5.7+ hoặc PostgreSQL). Tuy nhiên, bạn vẫn có thể làm việc với JSON trong SQLite bằng cách sử dụng các hàm chuỗi của SQLite và các hàm JSON của PHP. Bạn có thể tìm hiểu thêm về sqlite có hỗ trợ json không.
Lưu trữ JSON trong SQLite
Bạn có thể lưu trữ dữ liệu JSON trong một cột kiểu TEXT.
<?php
$db = new SQLite3('mydatabase.db');
$data = array('name' => 'John Doe', 'age' => 30, 'city' => 'New York');
$json = json_encode($data);
$stmt = $db->prepare('INSERT INTO mytable (data) VALUES (:data)');
$stmt->bindValue(':data', $json, SQLITE3_TEXT);
$result = $stmt->execute();
$db->close();
?>
Lấy dữ liệu JSON từ SQLite
Bạn có thể lấy dữ liệu JSON từ SQLite và giải mã nó bằng hàm json_decode
của PHP.
<?php
$db = new SQLite3('mydatabase.db');
$stmt = $db->prepare('SELECT data FROM mytable WHERE id = :id');
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray();
$json = $row['data'];
$data = json_decode($json, true); // Tham số true để trả về một mảng kết hợp
echo "Name: " . $data['name'] . "<br>";
echo "Age: " . $data['age'] . "<br>";
echo "City: " . $data['city'] . "<br>";
$db->close();
?>
Sử dụng các hàm chuỗi của SQLite để thao tác với JSON
Mặc dù SQLite không có các hàm JSON tích hợp sẵn, bạn có thể sử dụng các hàm chuỗi của nó để thực hiện các thao tác cơ bản với JSON. Ví dụ: bạn có thể sử dụng hàm SUBSTR
để trích xuất một phần của chuỗi JSON, hoặc hàm REPLACE
để thay thế một giá trị trong chuỗi JSON. Tuy nhiên, việc này có thể trở nên phức tạp và dễ xảy ra lỗi đối với các cấu trúc JSON phức tạp.
Kết luận
SQLite là một lựa chọn tuyệt vời cho các ứng dụng PHP nhỏ và vừa, đặc biệt là khi bạn cần một giải pháp cơ sở dữ liệu đơn giản, di động và không đòi hỏi nhiều tài nguyên. Bằng cách hiểu rõ cách SQLite hoạt động trong PHP và áp dụng các kỹ thuật tối ưu hóa, bạn có thể xây dựng các ứng dụng web hiệu quả và đáng tin cậy. Hãy bắt đầu khám phá và thử nghiệm SQLite trong dự án PHP tiếp theo của bạn!
FAQ (Câu Hỏi Thường Gặp)
1. SQLite có miễn phí không?
Có, SQLite là phần mềm mã nguồn mở và hoàn toàn miễn phí để sử dụng cho cả mục đích cá nhân và thương mại.
2. SQLite có thể thay thế MySQL không?
Trong một số trường hợp nhất định, SQLite có thể thay thế MySQL cho các ứng dụng nhỏ và vừa. Tuy nhiên, MySQL phù hợp hơn cho các ứng dụng lớn, phức tạp với yêu cầu về khả năng mở rộng và độ tin cậy cao.
3. Làm thế nào để bảo mật cơ sở dữ liệu SQLite?
SQLite không có tính năng bảo mật tích hợp sẵn như xác thực người dùng. Bạn cần tự xử lý các vấn đề bảo mật, ví dụ như mã hóa dữ liệu và kiểm soát truy cập tệp.
4. SQLite có giới hạn về kích thước cơ sở dữ liệu không?
Về mặt kỹ thuật, SQLite có thể hỗ trợ cơ sở dữ liệu lên đến 140TB. Tuy nhiên, hiệu suất có thể bị ảnh hưởng khi làm việc với các cơ sở dữ liệu lớn.
5. Làm thế nào để sao lưu cơ sở dữ liệu SQLite?
Vì cơ sở dữ liệu SQLite là một tệp duy nhất, bạn có thể sao lưu nó bằng cách đơn giản sao chép tệp đó.
6. SQLite có hỗ trợ stored procedures không?
Không, SQLite không hỗ trợ stored procedures.
7. Tôi nên sử dụng SQLite3 class hay PDO để kết nối đến SQLite trong PHP?
PDO là lựa chọn tốt hơn nếu bạn muốn có tính linh hoạt và khả năng chuyển đổi sang các loại cơ sở dữ liệu khác trong tương lai. SQLite3 class có thể nhanh hơn trong một số trường hợp cụ thể. Bạn có thể tìm hiểu thêm về cài đặt sqlite trên ubuntu.