개요
다음과 같이이 문서의 구조는 다음과 같다 :
- 보기 (보기)
- 인덱스 (지수)
- 트리거 (트리거)
- 트랜잭션 (거래)
전망
보기 (보기) 또는 가상 테이블은 또한 그 내용은 다른 테이블의 결과에서 파생, 파생 테이블을했다. 뷰는 기본 테이블처럼 보이지만 기본 테이블의 내용이-오래 지속하기 때문에 그것은 기본 테이블이 아니며, 내용보기는 동적으로 생성 사용하는 경우이다하지만. 다음과 같이 작성보기 구문은 다음과 같습니다
CREATE VIEW name AS select-stmt;
정의 된 선택-STMT에 의해 정의되는 이름으로 지정된 뷰의 이름입니다. 마지막으로 생성 된 뷰는 기본 테이블 이름의 이름처럼 보인다. 우리는 다음과 같은 이유로보기를 사용하는 경향이 :
- SQL 문을 재사용.
- 복잡한 SQL 작업을 간소화 할 수 있습니다. 쿼리를 작성 후, 당신은 쉽게 기본적인 조회 상세 내역을 알 수없이 다시 사용할 수 있습니다.
- 대신 테이블을 사용하여 전체 테이블의 일부입니다.
- 데이터를 보호 할 수 있습니다. 당신은 오히려 전체 테이블에 대한 접근보다는 테이블의 특정 부분에 대한 액세스 권한을 부여 할 수 있습니다.
- 데이터 형식 및 프리젠 테이션을 변경합니다. 테이블의 다른보기가 기본이되는 데이터 형식을 나타냅니다 반환 할 수 있습니다.
다음 예는 데이터의 검색 보면 :
SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num
AND prod_id = 'RGAN01';
이 예는 세 개의 테이블을 조인, 그리고 "RGAN01"로 prod_id 고객 정보를 검색 할 수 있습니다. 우리는 고객 정보의 "DLL01"로 prod_id 검색해야하는 경우, 명령의 긴 목록의 상단에 다시,이 시간, 우리가 함께 재사용 가능한 부품의 사용 가능성에 대한 전망을 고려할 수 다시 입력했다. 다음과 같습니다 :
CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num;
뷰를 생성 한 후 다음과 같이 우리는이 뷰를 사용할 수 있습니다 :
입력 :
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';
출력 :
cust_name cust_contact
---------- ------------------
Fun4All Denise L. Stephens
The Toy St Kim Howard
보기, 우리는 몇 가지 SQL 문을 생략 할 수 있습니다, 우리는 고객이 "DLL01"로, 당신은 SQL 문을 이전만큼 입력을하지 않아도 prod_id 조회 할 경우, 자사의 재사용 성을 향상시킬 수 있습니다.
참고 :
다른 단어를 검색 할 때 뷰를 사용하는 SQLite는에 SQLite는 갱신 가능한 뷰가 지원되지 않습니다.
자신의 재사용 성을 고려할 때 뷰를 만들려고 할 경우, 뷰를 생성하는 것은 특정 데이터에 바인딩되지는 종종 좋은 선택이 될 것입니다.
당신이보기를 제거해야하는 경우, 단순히 다음 명령을 실행합니다 :
DROP VIEW ProductsCustomers;
둘째, 인덱스
인덱스 (지수) 쿼리 속도를 높이기 위해 사용되는 특정 조건에서 구조입니다. 검색을 기존은 다음과 같습니다 :
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id = '100000002';
정상적인 상황, 데이터베이스 순차적 스캔, 모든 행을 검색 테이블에서 하나 하나에서, 준수는 '1000000002'= 출력 문을 CUST_ID. Customers 테이블이 매우 큰 경우에, 다음 매우 비효율적이 될 것이다 데이터를 검색이 방법은, 우리는 B 트리 인덱스의 사용을 기본 색인 검색 속도, SQLite는의 사용을 촉진하는 방법을 고려할 수 있습니다.
다음과 같이 인덱스 명령을 만듭니다
CREATE INDEX [UNIQUE] index_name ON table_name (columns);
INDEX_NAME가 TABLE_NAME 인덱스 테이블의 이름 필드를 포함하는 인덱스 변수의 이름 변수 항목은 쉼표로 구분에서 필드 또는 필드이다.
인덱스에 제약 조건을 추가 할 것입니다, 키워드 UNIQUE 사용하는 경우, 인덱스의 모든 값은 고유해야합니다. 이것은 또한, 인덱스 만에 있지 적용되는 필드 인덱스에 적용됩니다. 다음 예는 다음과 같다 :
sqlite> CREATE TABLE Foo(a text, b text);
sqlite> CREATE UNIQUE INDEX Foo_idx ON Foo(a,b);
sqlite> INSERT INTO Foo VALUES('unique', 'value');
sqlite> INSERT INTO Foo VALUES('unique', 'value1');
sqlite> INSERT INTO Foo VALUES('unique', 'value');
Error: UNIQUE constraint failed: Foo.a, Foo.b
관절 필드 값 중복, 그것은 오류 때 우리는 오류 메시지에서 볼 수 있습니다. 인덱스를 제거하려면, 드롭 INDEX 명령을 사용합니다 :
DROP INDEX Foo_idx;
참고 :
- 인덱스가 우리의 검색 속도를 빠르게 할 수 있지만 인덱스 데이터는 다중 테이블 인덱스의 모든 필드가 생성 특히, 저장 공간을 많이 차지해야 할 수도 있지만, 테이블의 크기는 두 배로 할 수있다.
- 고려해야 할 또 다른 문제는 인덱스 유지 보수입니다. 삽입, 업데이트 및 테이블을 수정뿐만 아니라, 삭제 작업을 할 때, 데이터베이스는 삽입, 업데이트 및 동작 속도 등이있는 경우, 인덱스가 감소 할 수있다 인덱스에 해당하는 수정 될 필요가있다.
- 마지막으로, (예를 들어, 국가 및 도시에 대한) 인덱스에 여러 열을 정의 할 때. 상태 플러스 도시로 순서를 정렬 할 때이 인덱스에만 유용합니다. 당신이 도시별로 정렬하려면,이 지수는 유용하지 않습니다.
1. 색인
SQLite는 인덱스를 사용할지 여부를 결정하기 위해 몇 가지 특정한 조건이있다. 다음 표현식은 WHERE 절에 나타납니다. SQLite는 단일 인덱스 필드를 사용합니다.
column { = | > | >= | <= | < } expression
expression { = | > | >= | <= | < } column
column IN (expression-list)
column IN (subquery)
다음의 몇 가지 예는 다음과 같이 테이블이 정의되어 있다고 가정, 설명 :
CREATE TABLE foo (a,b,c,d);
이 시점에서 인덱스는 다음 필드의 이상을 만들 수 있습니다 :
create index foo_idx on foo(a,b,c,d);
검색을 다음과 같습니다 :
SELECT * FROM foo WHERE a=1 AND b=2 AND d=3;
단지 제 1 및 제 2 조건은 인덱스를 사용합니다. 제 3 조건을 사용하지 않는 이유는, 갭 (D)을 좁히는 C를 사용하여 어떠한 조건 없다. 절 찾을 수없는 WHERE 때까지 필드 왼쪽에서 시작 다중 필드 인덱스 지능적으로 필드를 사용하여 쿼리 필드를 사용할 때 SQLite는 잘 사용 왼쪽, 다음, 그래서 두 번째 필드로 이동하고, 효과적인 조건.
SELECT * FROM foo WHERE a>1 AND b=2 AND c=3 AND d=4;
SQLite는 인덱스 스캔, A는, 식 A> 1 개 인덱스 필드는이 오른쪽라는 필드에서 수행됩니다 그것은 불평등을 사용하기 때문에 . 마찬가지로, 다음 명령문은 B> 2에서 중지됩니다
SELECT * FROM foo WHERE a=1 AND b>2 AND c=3 AND d=4;
모두 모두, 달성 될 수있는 개선 된 성능을 보장하는 좋은 이유가 있어야 인덱스를 생성, 그렇지 않으면 부정적인 최적화가있을 수 있습니다.
세 번째로, 플립 플롭
특정 데이터베이스 활동이 발생하면 트리거 (트리거)가 자동으로 실행. 그것은 특정 테이블 INSERT, UPDATE 트리거와 연관된 DELETE (또는 조합) 연산 할 수있다. 다음과 같이 트리거 명령을 생성 할 일반 :
CREATE [TEMP|TEMPORARY] TRIGGER trigger_name
[BEFORE|AFTER] [INSERT|DELETE|UPDATE|UPDATE OF columns] ON table_name
BEGIN
-- trigger logic goes here...
END;
트리거는 이름, 행동과 테이블 정의가 있습니다. 특정 이벤트가 발생했을 때, 트리거가이 명령을 시작하기에 대한 책임, SQL의 일련의 명령을 실시한다. 또한 전이나 작업이 후 또는 사고 발생 전에 수행 한 후 이러한 키워드를 지정할 수 있습니다. 상기 테이블에 UPDATE 트리거 생성 열 이상의 지정된 필드 일 수있다.
다음은 트리거의 몇 가지 일반적인 용도는 다음과 같습니다
- 데이터 일관성을 보장합니다. 예를 들어, INSERT 또는 UPDATE 작업 상태에있는 모든 대문자로 변환.
- 다른 테이블에서 활동의 구현에 테이블의 변화를 기준으로합니다. 예를 들어, 행이 갱신 또는 삭제할 때마다 감사 추적 기록은 로그 테이블에 기록.
- 추가 데이터를 확인하고 롤백 할 필요가 있었다. 예를 들어, 차단 삽입을 초과 한 경우 고객이 사용 가능한 자금의 한도를 초과하지 않도록한다.
- 타임 스탬프 값 또는 계산 된 열을 업데이트.
다음은 트리거의 간단한 예입니다 :
CREATE TABLE Company
(
id integer PRIMARY KEY,
name text NOT NULL,
address text NOT NULL
);
CREATE TABLE log(
emp_id integer,
emp_date text
);
두 테이블, 기록 작업에 대한 테이블베이스와 테이블 회사 로그를 생성합니다. 다음으로, 트리거를 만들 :
CREATE TRIGGER log_trigger AFTER INSERT ON Company
BEGIN
INSERT INTO log VALUES(new.id, datetime('now'));
END;
우리는 다음 몇 삽입 데이터 유효성 검사를 트리거 효과를 만들려고 한 후 :
INSERT INTO Company VALUES(null, 'Baidu', 'Beijing');
INSERT INTO Company VALUES(null, 'Alibaba', 'HangZhou');
INSERT INTO Company VALUES(null, 'Tencent', 'ShenZhen');
SELECT * FROM log;
emp_id emp_date
---------- -------------------
1 2019-04-23 01:18:30
2 2019-04-23 01:18:45
3 2019-04-23 01:18:47
볼 수있다, 우리는 해당 테이블에 로그 정보를 저장하는 트리거 삽입 작업을 통해 시간을 기록 할 수 있습니다.
참고 :
다른 DBMS에서 각 문 트리거를 지원하는 각 행 트리거를 지원할 수 있습니다. 그러나 각 행 트리거 만 SQLite는 지원, 즉, 영향을받는 각 행에 대해 운영 진술은 그가 한 번 트리거 될 때.
당신이 방아쇠를 나열 할 경우, 당신은있는 sqlite_master 도움이 될 수 있습니다 :
SELECT name FROM sqlite_master WHERE type = 'trigger';
name
-----------
log_trigger
트리거가 똑같이 단순 삭제 :
DROP TRIGGER log_trigger;
넷째, 트랜잭션
SQLite는 지원 서비스 작업, 트랜잭션 작업을 지원하는 데이터베이스는 네 가지 속성을 ACID 트랜잭션을 지원해야한다는 것을 의미합니다.
재산 | 기술 |
---|---|
원 자성 (자성) | 자성은 모든 성공 중 하나를 포함 트랜잭션의 모든 작업을 의미, 또는 모든 작업이 성공하면, 그들은 그렇지 않으면 데이터베이스에 어떤 영향을 미칠 수, 데이터베이스 응용 프로그램 트랜잭션을 완료해야합니다, 즉, 롤백 실패 |
일관성 (Consustency) | 일관성은가 일관성있는 상태에 있어야합니다 전에 트랜잭션 실행과 구현 후,이다, 또 다른 일관된 상태로 하나의 일관된 상태에서 데이터베이스를 변환해야하는 거래를 말한다 |
절연 (절연) | 동시에 다수의 트랜잭션들에 사이에 격리 같은 테이블과 같은 운영 사용자 데이터베이스에 동시에 액세스하는 복수의 개방 각 사용자 거래 데이터베이스는 다른 회사 간섭 될 수없는 격리, |
영구 (내구성) | 지속성은 트랜잭션이 커밋되면, 다음도 데이터베이스 시스템의 실패의 경우, 영구적 데이터베이스의 데이터에 커밋 된 트랜잭션의 작동되지 않은 손실을 변경하는 것을 의미한다 |
1. 명령 문제
업무는 세 가지 명령에 의해 제어되어, 시작 커밋 및 롤백. 열린 트랜잭션을 시작, 모든 작업은 연결이 전에 취소됩니다 종료되는 경우 커밋 발행하지 않았다 취소 후 시작할 수 있습니다. 트랜잭션이 수행 한 모든 작업을 확인하기 시작했다 커밋합니다. 롤백이 작업은 결국 시작 복원하는 것입니다. 예를 들면 :
sqlite> begin;
sqlite> DELETE FROM Products;
sqlite> rollback;
sqlite> SELECT count(*) FROM Products;
count(*)
----------
9
이 예는 롤백에서 수행 트랜잭션이 다음 제품에있는 모든 데이터를 삭제 열립니다 때문에 쿼리가 다시 데이터는 여전히 제품 존재하는 경우.
기본적으로 트랜잭션에서 각 SQL 문에서 SQLite는에 의해 (자동 모드 커밋). 즉, SQLite는 트랜잭션의 / 롤백,이 경우, 모든 성공 명령이 자동으로 작동 모드도 자동으로 알려져, 실패한 명령은 롤백되고 제출됩니다 커밋 ... 문 시작 한 각 개별 SQL 기본 모드를 커밋합니다.
2. 예약 된 자리를 사용하여
SQLite는 지원 세이브 포인트 및 해제 주문, 작업은 여러 문이 세이브 포인트로 돌아갈 수 있습니다 롤백, 세이브 포인트를 설정할 수 있습니다 구성되어있다. 다음과 같이 세이브 포인트 명령은 생성 :
savepoint savepoint_name;
다시 어딘가로 가을의 필요성의 인식이 전체 트랜잭션을 롤백하지 않는 경우, 롤백은 다음 명령을 사용할 수 있습니다 :
rollback [transaction] to savepoint_name;
예는 그것의 사용에서 보여주기 위해, 모두의 첫 번째의 후속 비교를 위해 고객 테이블 정보를 살펴 보자 :
sqlite> select cust_id, cust_name from Customers;
cust_id cust_name
---------- ------------
1000000001 Village Toys
1000000002 Kids Place
1000000003 Fun4All
1000000004 Fun4All
1000000005 The Toy Stor
그런 다음 우리는 트랜잭션이 보유 포인트를 포함하는 실행 :
begin;
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000010', 'Toys Emporium');
savepoint one;
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000008', 'Toys Moyu');
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000007', 'Toys JKLove');
rollback to one;
commit;
거래의 구현이 다시 한 점 실제로에만 CUST_ID 삽입이 데이터 1000000010로입니다 예약에 압연 이론적 후,의에 의해 이러한 쿼리 여부를 살펴 보자 :
sqlite> select cust_id, cust_name from Customers;
cust_id cust_name
---------- ------------
1000000001 Village Toys
1000000002 Kids Place
1000000003 Fun4All
1000000004 Fun4All
1000000005 The Toy Stor
1000000010 Toys Emporiu
당신은 정말에만 약 세이브 포인트 사용입니다 새로 삽입 된 문장을 볼 수 있습니다.
고정 지점을 개방하는 명령을 해제 릴리스는, 예를 들면, 다음 트랜잭션 오류를 생성 할 때를 결정하는데 사용되지 않을 것이다 저장 점에서 수행 될 필요 :
begin;
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000010', 'Toys Emporium');
savepoint one;
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000008', 'Toys Moyu');
INSERT INTO Customers(cust_id, cust_name) VALUES('1000000007', 'Toys JKLove');
release one;
rollback to one;
commit;
Error: no such savepoint: one
후자의 경우 첫 번째 중 하나가 해제 될 한 지점의 사용으로 예약됩니다, 다음 롤백 문이 하나의 경우에서 찾을 수 없습니다 원인이됩니다.
3. 분쟁 해결
때 제약 조건 위반이 트랜잭션이 종료됩니다. (데이터베이스의 대부분을 처리하는) 모든의 폐지 전에 수정 된 단지의 결과의 종료에 더하여, SQLite는 다음과 같은 옵션을 제공합니다 :
전술 | 기술 |
---|---|
바꾸다 | 고유 제약 조건 위반이, SQLite는이 레코드에 위반 될 때 새 레코드 또는 수정 대안을 삽입, 삭제, SQLite는 계속; 위반이 null 제약과 필드가 디폴트없는 경우, SQLite는 응용 프로그램이 전략을 중단 |
무시 | 제약 조건 위반이 발생하면, SQLite는 명령이 실행, 제약 조건 위반이 동일하게 유지하지만, 이전과 이후가 레코드를 수정하는 것을 계속할 수 있습니다 |
실패 | 제약 조건 위반이 발생하면 제약 조건 위반이 기록을 수정하기 전에, SQLite는 종료 명령은, 그러나 복구하지 않습니다 |
중단 | 제약 조건 위반이 발생하면, SQLite는 명령은 모든 변경 만들어 명령을 종료를 복원합니다. SQLite는은 기본적으로 모든 작업 솔루션을 중단한다 |
롤백 | 제약 조건 위반이 발생하면, SQLite는 롤백을 수행 - 현재 명령 및 전체 트랜잭션을 종료 |
다음과 같이 충돌 해결 구문은 다음과 같습니다
INSERT OR resolution INTO table_name (column_list) VALUES (value_list);
UPDATE OR resolution table_name SET (value_list) WHERE predicate;
그것의 실시를 사용 할 수있는 예제를 따라, 우리는 다음 표를 가정 하였다 :
CREATE TABLE test(id integer PRIMARY KEY);
SELECT count(*) FROM test;
count(*)
----------
412
이것은 데이터 (412)의 행 (412)의 데이터 1 내지 전체를 포함한다. 이제 다음 업데이트를 수행합니다
UPDATE test SET id=800-id;
Error: UNIQUE constraint failed: test.id
우리는 UPDATE 문이 첫 번째 388 개 레코드를 업데이트 할 때,이 ID가 800-388 = 412으로 업데이트,하지만 시험에서 412 이미 존재하는, 그래서 명령이 종료 볼 것입니다 있기 때문에, 고유성 제약 조건을 위반 볼 수 있습니다. 이전의 분석에 따르면, 우리는 377 개 업데이트 성공 기록의 앞에 취소됩니다 말을하는 것입니다 기본 실행 중단 전략이라고 알고있다.
우리가 성공적으로 업데이트 할 수있다 (377) 이전 기록을 유지하려면, 우리는 다음과 같은 명령을 입력 할 수 있습니다 :
UPDATE OR FAIL test SET id=800-id;
정책 실패 설정하면 보존 377 개 레코드의 앞을 변경할 수 있습니다.
참고
"SQLite는 확실한 가이드"
- 제 4 장 SQLite는 고급 SQL
"알고 있어야 SQL이 될 것"
- 제 18 개보기 사용
- 제 20과 트랜잭션 관리
- 제 22 개 고급 SQL 기능
나는 ~이 문서가 당신을 도울 수 있도록 노력하겠습니다