From 7e08cb3f04e67a5d162c671e3edbb2f1dea8bfc9 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Sat, 12 Nov 2022 00:52:00 +0800 Subject: [PATCH] sql debug --- .gitignore | 3 +- sql/db_create.sql | 6 +- sql/db_create_sqlite.sql | 152 +++++++++++++++++++++++++++++++++++++++ sql/trigger_sqlite.sql | 62 ++++++++++++++++ src/test/test_sqlite.py | 0 表设计.xlsx | Bin 50546 -> 50562 bytes 6 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 sql/db_create_sqlite.sql create mode 100644 sql/trigger_sqlite.sql create mode 100644 src/test/test_sqlite.py diff --git a/.gitignore b/.gitignore index 63af88a..3530448 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ *.tmp $* ~$* -.$* \ No newline at end of file +.$* +*.db \ No newline at end of file diff --git a/sql/db_create.sql b/sql/db_create.sql index 3353906..9cac25c 100644 --- a/sql/db_create.sql +++ b/sql/db_create.sql @@ -87,7 +87,7 @@ create table book_author author_id int NOT NULL, book_id int NOT NULL, PRIMARY KEY (`author_id`, `book_id`), -CONSTRAINT `fk_ba_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`), +CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; @@ -96,11 +96,11 @@ create table book_type type_id int NOT NULL, book_id int NOT NULL, PRIMARY KEY (`type_id`, `book_id`), -CONSTRAINT `fk_bt_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`), +CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -create table book_type +create table user_stat ( user_id int PRIMARY KEY, user_usedspace int NOT NULL DEFAULT 0, diff --git a/sql/db_create_sqlite.sql b/sql/db_create_sqlite.sql new file mode 100644 index 0000000..d163c5b --- /dev/null +++ b/sql/db_create_sqlite.sql @@ -0,0 +1,152 @@ +drop table if exists `admin`; +drop table if exists user; +drop table if exists book; +drop table if exists document; +drop table if exists note; +drop table if exists record; +drop table if exists typetable; +drop table if exists author; +drop table if exists book_author; +drop table if exists book_type; +drop table if exists user_stat; +create table `admin` +( + passwd varchar(100) NOT NULL +); +-- insert into `admin` (`passwd`) values(''); +-- sqlite default no foreign key +PRAGMA FOREIGN_KEYS=ON; + +-- user +drop table if exists user; +create table user +( +user_id INTEGER PRIMARY KEY AUTOINCREMENT, +user_name varchar(100) NOT NULL UNIQUE, +user_mail varchar(100) NOT NULL UNIQUE, +user_passwd varchar(100) NOT NULL, +user_limit int NOT NULL, +user_regtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +); +-- insert into user (`user_name`, `user_mail`, `user_passwd`, `user_limit`) values ('catfood', 'a@a.com', 'lil0', 100); + +-- book +drop table if exists book; +create table book +( +book_id INTEGER PRIMARY KEY AUTOINCREMENT, +book_name varchar(100) NOT NULL, +book_isbn varchar(100) DEFAULT NULL, +book_publisher varchar(100) DEFAULT NULL, +book_pubdate datetime DEFAULT NULL, +book_lang varchar(100) DEFAULT NULL, +user_id int NOT NULL, +CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE RESTRICT +); + +-- insert into book (`book_name`, `book_isbn`, `book_publisher`, `book_pubdate`, `book_lang`, `user_id`) values ('mom pig', 'emm', NULL, NULL, 'CN', 1); + +-- document +drop table if exists document; +create table document +( +doc_id INTEGER PRIMARY KEY AUTOINCREMENT, +doc_name varchar(100) NOT NULL, +doc_url varchar(100) NOT NULL, +doc_size int NOT NULL, +doc_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, +doc_type varchar(100) NOT NULL, +book_id int NOT NULL, +user_id int NOT NULL, +CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE RESTRICT, +CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT +); +create index `idx_doc_name` on document(doc_name); + +-- insert into document (`doc_name`,`doc_url`,`doc_size`,`doc_type`,`book_id`,`user_id`) values ("a.pdf", 'c:/shit/a.pdf', 10, 'pdf', 1, 1); + +-- note +drop table if exists note; +create table note +( +note_id INTEGER PRIMARY KEY AUTOINCREMENT, +note_name varchar(100) NOT NULL, +note_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, +note_content text NOT NULL DEFAULT '', +book_id int NOT NULL, +user_id int NOT NULL, +CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE RESTRICT, +CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT +); +create index `idx_note_name` on note(note_name); + +-- insert into note (`note_name`, `note_content`,`book_id`,`user_id`) values ('long ago', 'well, nothing', 1, 1); + +-- record +drop table if exists record; +create table record +( +record_time timestamp PRIMARY KEY DEFAULT CURRENT_TIMESTAMP, +record_type varchar(10) NOT NULL, +doc_URL varchar(100) NOT NULL, +user_id int NOT NULL +); + +-- insert into record (`record_type`,`doc_URL`,`user_id`) + -- values ('write', 'c:\a.pdf', 1); + +-- typetable +drop table if exists typetable; +create table typetable +( +type_id INTEGER PRIMARY KEY AUTOINCREMENT, +type_name varchar(20) NOT NULL UNIQUE +); +-- insert into typetable (`type_name`) values ('sjot'); + +-- author +drop table if exists author; +create table author +( +author_id INTEGER PRIMARY KEY AUTOINCREMENT, +author_name varchar(50) NOT NULL +); +create index `idx_author_name` on author(author_name); +-- insert into author (`author_name`) values ('alabama.shit'); + +-- book_author +drop table if exists book_author; +create table book_author +( +author_id int NOT NULL, +book_id int NOT NULL, +PRIMARY KEY (`author_id`, `book_id`), +CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT, +CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`) ON DELETE RESTRICT +); +-- insert into book_author values (1,1); + +-- book_type +drop table if exists book_type; +create table book_type +( +type_id int NOT NULL, +book_id int NOT NULL, +PRIMARY KEY (`type_id`, `book_id`), +CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT, +CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`) ON DELETE RESTRICT +); +-- insert into book_type values (1,1); + +-- user_stat +drop table if exists user_stat; +create table user_stat +( +user_id int PRIMARY KEY, +user_usedspace int NOT NULL DEFAULT 0, +user_bookcount int NOT NULL DEFAULT 0, +user_doccount int NOT NULL DEFAULT 0, +user_notecount int NOT NULL DEFAULT 0, +CONSTRAINT `fk_user_stat_user` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE RESTRICT +); +-- insert into user_stat values (1,1,1,1,1); \ No newline at end of file diff --git a/sql/trigger_sqlite.sql b/sql/trigger_sqlite.sql new file mode 100644 index 0000000..98fa53c --- /dev/null +++ b/sql/trigger_sqlite.sql @@ -0,0 +1,62 @@ +drop trigger if exists `trig_create_user_stat`; +create trigger `trig_create_user_stat` + after insert on user + for each row begin + insert into user_stat (`user_id`) values(NEW.user_id); +end; + +drop trigger if exists `trig_delete_user_stat`; +create trigger `trig_delete_user_stat` + after delete on user + for each row begin + delete from user_stat where user_id=OLD.user_id; +end; + +drop trigger if exists `trig_update_stat_book_ins`; +create trigger `trig_update_stat_book_ins` + after insert on book + for each row begin + update user_stat set user_bookcount=user_bookcount+1 where user_stat.user_id=NEW.user_id; +end; + + +drop trigger if exists `trig_update_stat_book_del`; +create trigger `trig_update_stat_book_del` + after delete on book + for each row begin + update user_stat set user_bookcount=user_bookcount-1 where user_stat.user_id=OLD.user_id; +end; + + +drop trigger if exists `trig_update_stat_doc_ins`; +create trigger `trig_update_stat_doc_ins` + after insert on document + for each row begin + update user_stat set user_doccount=user_doccount+1 where user_stat.user_id=NEW.user_id; + update user_stat set user_usedspace=user_usedspace+NEW.doc_size where user_stat.user_id=NEW.user_id; +end; + + +drop trigger if exists `trig_update_stat_doc_del`; +create trigger `trig_update_stat_doc_del` + after delete on document + for each row begin + update user_stat set user_doccount=user_doccount-1 where user_stat.user_id=OLD.user_id; + update user_stat set user_usedspace=user_usedspace-OLD.doc_size where user_stat.user_id=OLD.user_id; +end; + + +drop trigger if exists `trig_update_stat_note_ins`; +create trigger `trig_update_stat_note_ins` + after insert on note + for each row begin + update user_stat set user_notecount=user_notecount+1 where user_stat.user_id=NEW.user_id; +end; + + +drop trigger if exists `trig_update_stat_note_del`; +create trigger `trig_update_stat_note_del` + after delete on note + for each row begin + update user_stat set user_notecount=user_notecount-1 where user_stat.user_id=OLD.user_id; +end; diff --git a/src/test/test_sqlite.py b/src/test/test_sqlite.py new file mode 100644 index 0000000..e69de29 diff --git a/表设计.xlsx b/表设计.xlsx index 7381e546c646a547f43de3cd584564225f79abad..24740fc3d95d670e581f8efe5bfb584a9241fcc7 100644 GIT binary patch delta 6556 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 N--rKXtLdK!{|DhLCNuy5