-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.sql
More file actions
executable file
·175 lines (162 loc) · 6.22 KB
/
Copy pathdatabase.sql
File metadata and controls
executable file
·175 lines (162 loc) · 6.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
DROP TABLE IF EXISTS order_items CASCADE;
DROP TABLE IF EXISTS orders CASCADE;
DROP TABLE IF EXISTS payments CASCADE;
DROP TABLE IF EXISTS favorites CASCADE;
DROP TABLE IF EXISTS comments CASCADE;
DROP TABLE IF EXISTS product_units CASCADE;
DROP TABLE IF EXISTS product_images CASCADE;
DROP TABLE IF EXISTS own_products CASCADE;
DROP TABLE IF EXISTS products CASCADE;
DROP TABLE IF EXISTS categories CASCADE;
DROP TABLE IF EXISTS product_variants CASCADE;
DROP TABLE IF EXISTS sellers CASCADE;
DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS admins CASCADE;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password TEXT NOT NULL,
phone VARCHAR(15),
address TEXT,
avatar_url TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE sellers (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password TEXT NOT NULL,
phone VARCHAR(15),
shop_name VARCHAR(100) NOT NULL,
shop_description TEXT,
logo_url TEXT,
is_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE admins (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
parent_id INT REFERENCES categories(id) ON DELETE SET NULL
);
INSERT INTO categories (name, parent_id) VALUES ('Root', NULL);
CREATE TABLE products (
id SERIAL PRIMARY KEY,
seller_id INT REFERENCES sellers(id) ON DELETE CASCADE,
user_id INT REFERENCES users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
brand TEXT,
category_id INT REFERENCES categories(id) ON DELETE SET NULL,
price INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
CHECK (
(seller_id IS NOT NULL AND user_id IS NULL)
OR
(seller_id IS NULL AND user_id IS NOT NULL)
)
);
CREATE TABLE product_variants (
id SERIAL PRIMARY KEY,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
size TEXT NOT NULL,
color TEXT NOT NULL,
quantity INT NOT NULL,
price INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(product_id, size, color)
);
CREATE TABLE product_images (
id SERIAL PRIMARY KEY,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
image_url TEXT NOT NULL,
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(product_id, image_url)
);
CREATE TABLE product_units (
id SERIAL PRIMARY KEY,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
variant_id INT REFERENCES product_variants(id) ON DELETE CASCADE,
qr_code TEXT UNIQUE NOT NULL,
blockchain_hash TEXT UNIQUE NOT NULL,
is_used BOOLEAN DEFAULT FALSE,
used_at TIMESTAMP DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE own_products (
id SERIAL PRIMARY KEY,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
is_seller BOOLEAN NOT NULL DEFAULT TRUE, -- TRUE = seller, FALSE = user
owner_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (product_id, is_seller, owner_id)
);
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
content TEXT NOT NULL,
sentiment INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE favorites (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
product_id INT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, product_id)
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
total_amount INT NOT NULL,
status INT DEFAULT 0 CHECK (status IN (0,1,2,3)), -- 0: pending, 1: shipped, 2: completed, 3: canceled
blockchain_hash TEXT UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INT NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
product_id INT NOT NULL REFERENCES products(id),
variant_id INT REFERENCES product_variants(id),
quantity INT NOT NULL CHECK (quantity > 0),
price INT NOT NULL,
total_price INT GENERATED ALWAYS AS (quantity * price) STORED
);
CREATE TABLE payments (
id SERIAL PRIMARY KEY,
order_id INT NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
method VARCHAR(50) NOT NULL CHECK (method IN ('QR_VNPay', 'Momo', 'ZaloPay', 'COD')),
transaction_id TEXT,
paid_amount INT,
status BOOLEAN DEFAULT FALSE, -- TRUE: paid, FALSE: pending
paid_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance optimization
CREATE INDEX idx_product_images_product_id ON product_images(product_id);
CREATE INDEX idx_product_variants_product_id ON product_variants(product_id);
CREATE INDEX idx_product_variants_multi ON product_variants(product_id, size, color);
CREATE INDEX idx_products_seller_id ON products(seller_id);
CREATE INDEX idx_products_user_id ON products(user_id);
CREATE INDEX idx_products_category_id ON products(category_id);
CREATE INDEX idx_products_name_lower ON products(LOWER(name));
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
CREATE INDEX idx_product_units_product_id ON product_units(product_id);
CREATE INDEX idx_product_units_qr_code ON product_units(qr_code);
CREATE INDEX idx_product_units_blockchain_hash ON product_units(blockchain_hash);
CREATE INDEX idx_favorites_user_id ON favorites(user_id);
CREATE INDEX idx_favorites_product_id ON favorites(product_id);
CREATE INDEX idx_comments_user_id ON comments(user_id);
CREATE INDEX idx_comments_product_id ON comments(product_id);
CREATE INDEX idx_payments_order_id ON payments(order_id);
CREATE INDEX idx_own_products_owner ON own_products(owner_id, is_seller);