SQLite는 연구 노트 (육)

면책 조항 : https://blog.csdn.net/qq_38182125/article/details/89453107 :이 문서는 블로거 원본입니다, 소스를 표시하시기 바랍니다

개요

다음과 같이이 문서의 구조는 다음과 같다 :

  • 보기 (보기)
  • 인덱스 (지수)
  • 트리거 (트리거)
  • 트랜잭션 (거래)

전망

보기 (보기) 또는 가상 테이블은 또한 그 내용은 다른 테이블의 결과에서 파생, 파생 테이블을했다. 뷰는 기본 테이블처럼 보이지만 기본 테이블의 내용이-오래 지속하기 때문에 그것은 기본 테이블이 아니며, 내용보기는 동적으로 생성 사용하는 경우이다하지만. 다음과 같이 작성보기 구문은 다음과 같습니다

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 기능

나는 ~이 문서가 당신을 도울 수 있도록 노력하겠습니다

추천

출처blog.csdn.net/qq_38182125/article/details/89453107