diff --git a/数据库应用系统的代码/main.py b/数据库应用系统的代码/main.py new file mode 100644 index 0000000..847bd14 --- /dev/null +++ b/数据库应用系统的代码/main.py @@ -0,0 +1,589 @@ +import tkinter as tk +from tkinter import messagebox, ttk +import pymysql + +# 创建连接 +conn = pymysql.connect( + host="localhost", + user="root", + password="123456", + database="online_store" +) + +# 创建游标对象 +mycursor = conn.cursor() + +# 创建Tkinter窗口 +root = tk.Tk() +root.title("数据库管理系统") + +# 定义角色列表 +roles = ["管理员", "商家", "消费者"] + +# 定义表名列表 +tables = ["User", "Product", "`Order`", "OrderDetail", "Review", "ShoppingCart", "PaymentRecord", "Logistics", + "Warehouse", "Merchant"] + + +# 获取表格列名 +def get_columns(table_name): + mycursor.execute(f"DESCRIBE {table_name}") + return [column[0] for column in mycursor.fetchall()] + + +# 清除所有标签页 +def clear_tabs(): + for tab_id in tab_control.tabs(): + tab_control.forget(tab_id) + + +# 增加数据功能(管理员模式) +def add_data(): + table_name = tab_add_widgets['table_combobox'].get() + if not table_name: + messagebox.showwarning("警告", "请选择一个表") + return + + columns = [] + values = [] + for column, entry in tab_add_widgets['entry_dict'].items(): + value = entry.get().strip() + if value: + columns.append(column) + values.append(value) + + if not columns or not values: + messagebox.showwarning("警告", "请输入至少一个列值") + return + + try: + query = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(values))})" + mycursor.execute(query, values) + conn.commit() + messagebox.showinfo("成功", "数据添加成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 删除数据功能(管理员模式) +def delete_data(): + table_name = tab_delete_widgets['table_combobox'].get() + condition_value = tab_delete_widgets['entry_condition'].get().strip() + + if not table_name or not condition_value: + messagebox.showwarning("警告", "请选择一个表并输入条件值") + return + + # 删除子表中的相关记录 + try: + if table_name == "User": + mycursor.execute(f"DELETE FROM Review WHERE {condition_value}") + mycursor.execute(f"DELETE FROM `Order` WHERE {condition_value}") + elif table_name == "Product": + mycursor.execute(f"DELETE FROM Review WHERE {condition_value}") + mycursor.execute(f"DELETE FROM OrderDetail WHERE {condition_value}") + + # 删除父表中的记录 + mycursor.execute(f"DELETE FROM {table_name} WHERE {condition_value}") + conn.commit() + messagebox.showinfo("成功", "数据删除成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 更新数据功能(管理员模式) +def update_data(): + table_name = tab_update_widgets['table_combobox'].get() + column_name = tab_update_widgets['column_combobox'].get() + new_value = tab_update_widgets['entry_update'].get().strip() + condition_value = tab_update_widgets['entry_condition'].get().strip() + + if not table_name or not column_name or not new_value or not condition_value: + messagebox.showwarning("警告", "请选择一个表、列名,并输入新值和条件值") + return + + try: + query = f"UPDATE {table_name} SET {column_name} = '{new_value}' WHERE {condition_value}" + mycursor.execute(query) + conn.commit() + messagebox.showinfo("成功", "数据更新成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 查询数据功能(管理员模式) +def execute_query(): + table_name = tab_query_widgets['table_combobox'].get() + if not table_name: + messagebox.showwarning("警告", "请选择一个表") + return + + try: + mycursor.execute(f"SELECT * FROM {table_name}") + columns = [desc[0] for desc in mycursor.description] + results = mycursor.fetchall() + + # 清空结果区 + tab_query_widgets['result_text'].delete("1.0", tk.END) + + # 显示列名 + tab_query_widgets['result_text'].insert(tk.END, f"{columns}\n") + + # 显示查询结果 + for row in results: + tab_query_widgets['result_text'].insert(tk.END, f"{row}\n") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 刷新列名和动态生成输入框 +def refresh_columns(table_name, tab): + if table_name: + columns = get_columns(table_name) + if 'column_combobox' in tab: + tab['column_combobox']['values'] = columns + + if 'dynamic_frame' in tab: + for widget in tab['dynamic_frame'].winfo_children(): + widget.destroy() + + tab['entry_dict'].clear() # 确保字典是空的 + for column in columns: + tk.Label(tab['dynamic_frame'], text=column).pack() + entry = tk.Entry(tab['dynamic_frame']) + entry.pack() + tab['entry_dict'][column] = entry + + +# 管理员模式功能 +def admin_mode(): + clear_tabs() + tab_control.add(tab_add, text='增加数据') + tab_control.add(tab_delete, text='删除数据') + tab_control.add(tab_update, text='更新数据') + tab_control.add(tab_query, text='查询数据') + tab_control.pack(expand=1, fill='both') + tab_add_widgets['table_combobox'].bind("<>", + lambda event: refresh_columns(tab_add_widgets['table_combobox'].get(), + tab_add_widgets)) + + +# 商家模式功能 +def merchant_mode(user_id): + clear_tabs() + tab_control.add(tab_add_product, text='增加商品') + tab_control.add(tab_query_own_products, text='管理自己的商品') + tab_control.pack(expand=1, fill='both') + + # 动态生成商品信息的输入框 + refresh_columns("Product", tab_add_product_widgets) + + # 显示当前商家的商品 + query_own_products(user_id) + + # 修改添加商品按钮,确保传递用户ID + tk.Button(tab_add_product, text="增加商品", command=lambda: add_product(user_id)).pack(pady=5) + + +def query_own_products(user_id): + try: + query = f""" + SELECT p.* + FROM Product_Merchant pm + JOIN Product p ON pm.ProductID = p.ProductID + WHERE pm.MerchantID = {user_id} + """ + print(query) # 打印SQL查询 + mycursor.execute(query) + columns = [desc[0] for desc in mycursor.description] + results = mycursor.fetchall() + + tab_query_own_products_widgets['result_text'].delete("1.0", tk.END) + tab_query_own_products_widgets['result_text'].insert(tk.END, f"{columns}\n") + for row in results: + tab_query_own_products_widgets['result_text'].insert(tk.END, f"{row}\n") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 增加商品功能(商家模式) +def add_product(user_id): + table_name = "Product" + columns = [] + values = [] + for column, entry in tab_add_product_widgets['entry_dict'].items(): + value = entry.get().strip() + if value: + columns.append(column) + values.append(value) + + if not columns or not values: + messagebox.showwarning("警告", "请输入至少一个列值") + return + + try: + # 插入商品到Product表 + query = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(values))})" + print(query) # 打印SQL查询 + mycursor.execute(query, values) + product_id = mycursor.lastrowid + + # 插入商品和商家的关联到Product_Merchant表 + query = f"INSERT INTO Product_Merchant (ProductID, MerchantID) VALUES (%s, %s)" + mycursor.execute(query, (product_id, user_id)) + + conn.commit() + messagebox.showinfo("成功", "商品添加成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 消费者模式功能 +def consumer_mode(user_id): + clear_tabs() + tab_control.add(tab_query_products, text='查询商品') + tab_control.add(tab_manage_cart, text='管理购物车') + tab_control.pack(expand=1, fill='both') + + # 显示当前消费者的购物车 + query_cart(user_id) + + +# 查询商品功能(消费者模式) +def query_products(): + table_name = "Product" + if not table_name: + messagebox.showwarning("警告", "请选择一个表") + return + + try: + mycursor.execute(f"SELECT * FROM {table_name}") + columns = [desc[0] for desc in mycursor.description] + results = mycursor.fetchall() + + tab_query_products_widgets['result_text'].delete("1.0", tk.END) + tab_query_products_widgets['result_text'].insert(tk.END, f"{columns}\n") + for row in results: + tab_query_products_widgets['result_text'].insert(tk.END, f"{row}\n") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 查询购物车功能(消费者模式) +def query_cart(user_id): + table_name = "ShoppingCart" + if not table_name: + messagebox.showwarning("警告", "请选择一个表") + return + + try: + query = f"SELECT * FROM {table_name} WHERE UserID = {user_id}" + mycursor.execute(query) + columns = [desc[0] for desc in mycursor.description] + results = mycursor.fetchall() + + tab_manage_cart_widgets['result_text'].delete("1.0", tk.END) + tab_manage_cart_widgets['result_text'].insert(tk.END, f"{columns}\n") + for row in results: + tab_manage_cart_widgets['result_text'].insert(tk.END, f"{row}\n") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + + +# 删除购物车项功能(消费者模式) +def delete_cart_item(): + table_name = "ShoppingCart" + condition_value = tab_delete_cart_item_widgets['entry_condition'].get().strip() + + if not table_name or not condition_value: + messagebox.showwarning("警告", "请输入条件值") + return + + try: + query = f"DELETE FROM {table_name} WHERE {condition_value}" + mycursor.execute(query) + conn.commit() + messagebox.showinfo("成功", "购物车项删除成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 更新购物车项数量功能(消费者模式) +def update_cart_item_quantity(): + table_name = "ShoppingCart" + new_value = tab_update_cart_item_quantity_widgets['entry_update'].get().strip() + condition_value = tab_update_cart_item_quantity_widgets['entry_condition'].get().strip() + + if not table_name or not new_value or not condition_value: + messagebox.showwarning("警告", "请输入新值和条件值") + return + + try: + query = f"UPDATE {table_name} SET Quantity = {new_value} WHERE {condition_value}" + mycursor.execute(query) + conn.commit() + messagebox.showinfo("成功", "购物车项数量更新成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 角色选择功能 +def role_selection(): + selected_role = role_combobox.get() + user_id = user_id_entry.get().strip() + if selected_role == "管理员": + admin_mode() + elif selected_role == "商家": + merchant_mode(user_id) + elif selected_role == "消费者": + consumer_mode(user_id) + + +# 创建角色选择界面 +tk.Label(root, text="选择角色:").pack(pady=5) +role_combobox = ttk.Combobox(root, values=roles) +role_combobox.pack(pady=5) + +tk.Label(root, text="用户ID:").pack(pady=5) +user_id_entry = tk.Entry(root) +user_id_entry.pack(pady=5) + +tk.Button(root, text="进入", command=role_selection).pack(pady=5) + +# 创建Tab控制 +tab_control = ttk.Notebook(root) + +# 创建增加数据Tab(管理员模式) +tab_add = ttk.Frame(tab_control) +tab_add_widgets = { + 'table_combobox': ttk.Combobox(tab_add, values=tables), + 'dynamic_frame': tk.Frame(tab_add), + 'entry_dict': {} +} + +tk.Label(tab_add, text="选择表:").pack(pady=5) +tab_add_widgets['table_combobox'].pack(pady=5) +tab_add_widgets['table_combobox'].bind("<>", + lambda event: refresh_columns(tab_add_widgets['table_combobox'].get(), + tab_add_widgets)) +tab_add_widgets['dynamic_frame'].pack(pady=5) +tk.Button(tab_add, text="增加数据", command=add_data).pack(pady=5) + +# 创建删除数据Tab(管理员模式) +tab_delete = ttk.Frame(tab_control) +tab_delete_widgets = { + 'table_combobox': ttk.Combobox(tab_delete, values=tables), + 'entry_condition': tk.Entry(tab_delete) +} + +tk.Label(tab_delete, text="选择表:").pack(pady=5) +tab_delete_widgets['table_combobox'].pack(pady=5) +tk.Label(tab_delete, text="输入条件值:").pack(pady=5) +tab_delete_widgets['entry_condition'].pack(pady=5) +tk.Button(tab_delete, text="删除数据", command=delete_data).pack(pady=5) + +# 创建更新数据Tab(管理员模式) +tab_update = ttk.Frame(tab_control) +tab_update_widgets = { + 'table_combobox': ttk.Combobox(tab_update, values=tables), + 'column_combobox': ttk.Combobox(tab_update), + 'entry_update': tk.Entry(tab_update), + 'entry_condition': tk.Entry(tab_update) +} + +tk.Label(tab_update, text="选择表:").pack(pady=5) +tab_update_widgets['table_combobox'].pack(pady=5) +tab_update_widgets['table_combobox'].bind("<>", + lambda event: refresh_columns(tab_update_widgets['table_combobox'].get(), + tab_update_widgets)) +tk.Label(tab_update, text="选择列:").pack(pady=5) +tab_update_widgets['column_combobox'].pack(pady=5) +tk.Label(tab_update, text="输入新值:").pack(pady=5) +tab_update_widgets['entry_update'].pack(pady=5) +tk.Label(tab_update, text="输入条件值:").pack(pady=5) +tab_update_widgets['entry_condition'].pack(pady=5) +tk.Button(tab_update, text="更新数据", command=update_data).pack(pady=5) + +# 创建查询数据Tab(管理员模式) +tab_query = ttk.Frame(tab_control) +tab_query_widgets = { + 'table_combobox': ttk.Combobox(tab_query, values=tables), + 'result_text': tk.Text(tab_query, height=10, width=80) +} + +tk.Label(tab_query, text="选择表:").pack(pady=5) +tab_query_widgets['table_combobox'].pack(pady=5) +tk.Button(tab_query, text="查询数据", command=execute_query).pack(pady=5) +tab_query_widgets['result_text'].pack(pady=5) + +# 创建增加商品Tab(商家模式) +tab_add_product = ttk.Frame(tab_control) +tab_add_product_widgets = { + 'dynamic_frame': tk.Frame(tab_add_product), + 'entry_dict': {} +} + +tk.Label(tab_add_product, text="输入商品信息:").pack(pady=5) +tab_add_product_widgets['dynamic_frame'].pack(pady=5) +tk.Button(tab_add_product, text="增加商品", command=add_product).pack(pady=5) + +# 创建管理自己商品Tab(商家模式) +tab_query_own_products = ttk.Frame(tab_control) +tab_query_own_products_widgets = { + 'result_text': tk.Text(tab_query_own_products, height=10, width=80) +} + +tk.Label(tab_query_own_products, text="管理自己的商品:").pack(pady=5) +tab_query_own_products_widgets['result_text'].pack(pady=5) + +# 创建查询商品Tab(消费者模式) +tab_query_products = ttk.Frame(tab_control) +tab_query_products_widgets = { + 'result_text': tk.Text(tab_query_products, height=10, width=80) +} + +tk.Label(tab_query_products, text="商品信息:").pack(pady=5) +tk.Button(tab_query_products, text="查询商品", command=query_products).pack(pady=5) +tab_query_products_widgets['result_text'].pack(pady=5) + + +# 增加购物车项功能(消费者模式) +def add_cart_item(): + table_name = "ShoppingCart" + columns = [] + values = [] + for column, entry in tab_add_cart_item_widgets['entry_dict'].items(): + value = entry.get().strip() + if value: + columns.append(column) + values.append(value) + + if not columns or not values: + messagebox.showwarning("警告", "请输入至少一个列值") + return + + try: + query = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(values))})" + print(query) # 打印SQL查询 + mycursor.execute(query, values) + conn.commit() + messagebox.showinfo("成功", "购物车项添加成功") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 刷新列名和动态生成输入框 +def refresh_cart_columns(table_name, tab): + if table_name: + columns = get_columns(table_name) + if 'dynamic_frame' in tab: + for widget in tab['dynamic_frame'].winfo_children(): + widget.destroy() + + tab['entry_dict'].clear() # 确保字典是空的 + for column in columns: + tk.Label(tab['dynamic_frame'], text=column).pack() + entry = tk.Entry(tab['dynamic_frame']) + entry.pack() + tab['entry_dict'][column] = entry + +# 查询数据功能(管理员模式) +def execute_query(): + table_name = tab_query_widgets['table_combobox'].get() + condition_value = tab_query_widgets['entry_condition'].get().strip() + if not table_name: + messagebox.showwarning("警告", "请选择一个表") + return + + try: + # 构造查询语句,加入条件值(如果有) + if condition_value: + query = f"SELECT * FROM {table_name} WHERE {condition_value}" + else: + query = f"SELECT * FROM {table_name}" + + mycursor.execute(query) + columns = [desc[0] for desc in mycursor.description] + results = mycursor.fetchall() + + # 清空结果区 + tab_query_widgets['result_text'].delete("1.0", tk.END) + + # 显示列名 + tab_query_widgets['result_text'].insert(tk.END, f"{columns}\n") + + # 显示查询结果 + for row in results: + tab_query_widgets['result_text'].insert(tk.END, f"{row}\n") + except pymysql.MySQLError as err: + messagebox.showerror("Error", f"Error: {err}") + + +# 更新查询数据Tab(管理员模式),增加条件输入框 +tab_query = ttk.Frame(tab_control) +tab_query_widgets = { + 'table_combobox': ttk.Combobox(tab_query, values=tables), + 'entry_condition': tk.Entry(tab_query), # 新增条件输入框 + 'result_text': tk.Text(tab_query, height=10, width=80) +} + +tk.Label(tab_query, text="选择表:").pack(pady=5) +tab_query_widgets['table_combobox'].pack(pady=5) +tk.Label(tab_query, text="输入查询条件 (可选):").pack(pady=5) # 条件标签 +tab_query_widgets['entry_condition'].pack(pady=5) # 条件输入框 +tk.Button(tab_query, text="查询数据", command=execute_query).pack(pady=5) +tab_query_widgets['result_text'].pack(pady=5) + +# 创建管理购物车Tab(消费者模式) +tab_manage_cart = ttk.Frame(tab_control) + +# 添加购物车项 +tab_add_cart_item_widgets = { + 'dynamic_frame': tk.Frame(tab_manage_cart), + 'entry_dict': {} +} + +tk.Label(tab_manage_cart, text="添加购物车项:").pack(pady=5) +tab_add_cart_item_widgets['dynamic_frame'].pack(pady=5) +tk.Button(tab_manage_cart, text="添加购物车项", command=add_cart_item).pack(pady=5) + +# 动态生成购物车项的输入框 +refresh_cart_columns("ShoppingCart", tab_add_cart_item_widgets) + +# 删除购物车项 +tab_delete_cart_item_widgets = { + 'entry_condition': tk.Entry(tab_manage_cart) +} + +tk.Label(tab_manage_cart, text="删除购物车项 - 输入条件:").pack(pady=5) +tab_delete_cart_item_widgets['entry_condition'].pack(pady=5) +tk.Button(tab_manage_cart, text="删除购物车项", command=delete_cart_item).pack(pady=5) + +# 更新购物车项数量 +tab_update_cart_item_quantity_widgets = { + 'entry_update': tk.Entry(tab_manage_cart), + 'entry_condition': tk.Entry(tab_manage_cart) +} + +tk.Label(tab_manage_cart, text="更新购物车项数量:").pack(pady=5) +tk.Label(tab_manage_cart, text="输入新数量:").pack(pady=5) +tab_update_cart_item_quantity_widgets['entry_update'].pack(pady=5) +tk.Label(tab_manage_cart, text="输入条件:").pack(pady=5) +tab_update_cart_item_quantity_widgets['entry_condition'].pack(pady=5) +tk.Button(tab_manage_cart, text="更新数量", command=update_cart_item_quantity).pack(pady=5) + +# 显示购物车项 +tab_manage_cart_widgets = { + 'result_text': tk.Text(tab_manage_cart, height=10, width=80) +} + +tk.Label(tab_manage_cart, text="购物车信息:").pack(pady=5) +tab_manage_cart_widgets['result_text'].pack(pady=5) + +# 运行Tkinter主循环 +root.mainloop() + +# 关闭连接 +conn.close() + diff --git a/数据库脚本/sql脚本.txt b/数据库脚本/sql脚本.txt new file mode 100644 index 0000000..22d34d5 --- /dev/null +++ b/数据库脚本/sql脚本.txt @@ -0,0 +1,1132 @@ +1.用户表: +CREATE TABLE User ( + UserID INT AUTO_INCREMENT PRIMARY KEY, + Username VARCHAR(50) NOT NULL UNIQUE, + Password VARCHAR(255) NOT NULL, + Email VARCHAR(100) NOT NULL UNIQUE, + PhoneNumber VARCHAR(15) NOT NULL UNIQUE, + RegistrationTime DATETIME NOT NULL, + AccountStatus ENUM('active', 'inactive', 'suspended') NOT NULL, + UserType ENUM('customer', 'merchant') NOT NULL, + AddressInfo TEXT +); + +INSERT INTO User (Username, Password, Email, PhoneNumber, RegistrationTime, AccountStatus, UserType, AddressInfo) +VALUES +('张三', 'password123', 'zhangsan@example.com', '13800138000', '2023-01-01 10:00:00', 'active', 'customer', '北京市朝阳区'), +('李四', 'password456', 'lisi@example.com', '13800138001', '2023-01-02 11:00:00', 'active', 'merchant', '上海市浦东新区'), +('王五', 'password789', 'wangwu@example.com', '13800138002', '2023-01-03 12:00:00', 'active', 'customer', '深圳市南山区'), +('赵六', 'password000', 'zhaoliu@example.com', '13800138003', '2023-01-04 13:00:00', 'inactive', 'customer', '广州市天河区'), +('钱七', 'password111', 'qianqi@example.com', '13800138004', '2023-01-05 14:00:00', 'active', 'merchant', '杭州市西湖区'), +('孙八', 'password222', 'sunba@example.com', '13800138005', '2023-01-06 15:00:00', 'active', 'customer', '南京市鼓楼区'), +('周九', 'password333', 'zhoujiu@example.com', '13800138006', '2023-01-07 16:00:00', 'active', 'customer', '武汉市武昌区'), +('吴十', 'password444', 'wushi@example.com', '13800138007', '2023-01-08 17:00:00', 'active', 'merchant', '成都市高新区'), +('郑十一', 'password555', 'zhengshi@example.com', '13800138008', '2023-01-09 18:00:00', 'inactive', 'customer', '长沙市岳麓区'), +('王十二', 'password666', 'wangshi@example.com', '13800138009', '2023-01-10 19:00:00', 'active', 'customer', '西安市碑林区'); + +2.商品表: +CREATE TABLE Product ( + ProductID INT AUTO_INCREMENT PRIMARY KEY, + ProductName VARCHAR(100) NOT NULL, + Description TEXT, + Price DECIMAL(10, 2) NOT NULL, + Status ENUM('listed', 'unlisted') NOT NULL, + Sales INT DEFAULT 0, + ImageURL VARCHAR(255), + StockQuantity INT NOT NULL +); + +INSERT INTO Product (ProductName, Description, Price, Status, Sales, ImageURL, StockQuantity) +VALUES +('华为 MateBook X Pro', '高性能笔记本,13.9英寸触控屏,i7处理器,16GB内存', 9999.99, 'listed', 50, 'https://example.com/images/matebook.jpg', 200), +('iPhone 15 Pro', '苹果旗舰手机,6.1英寸OLED屏,A17芯片,128GB存储', 7999.99, 'listed', 150, 'https://example.com/images/iphone15.jpg', 300), +('Sony WH-1000XM5', '高质量降噪耳机,30小时续航,支持蓝牙连接', 2999.99, 'listed', 200, 'https://example.com/images/sony_headphones.jpg', 100), +('Apple Watch Ultra', '专业运动手表,超长续航,支持心率监测和GPS定位', 4999.99, 'listed', 80, 'https://example.com/images/apple_watch.jpg', 150), +('小米电视 4A', '4K超高清电视,支持HDR,声音环绕技术', 2499.99, 'listed', 300, 'https://example.com/images/xiaomi_tv.jpg', 500), +('iPad Air 5', '平板电脑,10.9英寸显示屏,支持Apple Pencil', 4999.99, 'listed', 120, 'https://example.com/images/ipad_air.jpg', 200), +('PlayStation 5', '次世代游戏主机,支持4K,极致游戏体验', 4999.99, 'listed', 150, 'https://example.com/images/ps5.jpg', 80), +('Bose SoundLink', '无线蓝牙音响,12小时续航,音质清晰', 1999.99, 'listed', 100, 'https://example.com/images/bose_speaker.jpg', 150), +('Canon EOS R5', '高端数码单反相机,45MP全画幅传感器,8K视频录制', 14999.99, 'listed', 50, 'https://example.com/images/canon_eos.jpg', 30), +('Logitech MX Master 3', '高性能无线鼠标,支持自定义按钮,舒适手感', 799.99, 'listed', 200, 'https://example.com/images/logitech_mouse.jpg', 250); + +3.订单表: +CREATE TABLE `Order` ( + OrderID INT AUTO_INCREMENT PRIMARY KEY, + UserID INT NOT NULL, + TotalPrice DECIMAL(10, 2) NOT NULL, + OrderStatus ENUM('pending', 'shipped', 'delivered', 'cancelled') NOT NULL, + CreationTime DATETIME NOT NULL, + PaymentTime DATETIME, + DeliveryAddress TEXT +); + +INSERT INTO `Order` (UserID, TotalPrice, OrderStatus, CreationTime, PaymentTime, DeliveryAddress) VALUES +(1, 999.99, 'pending', '2024-02-01 10:00:00', NULL, '123 Main St'), +(2, 1249.98, 'shipped', '2024-02-02 11:00:00', '2024-02-03 10:00:00', '456 Elm St'), +(3, 149.99, 'delivered', '2024-02-03 12:00:00', '2024-02-03 13:00:00', '789 Oak St'), +(4, 79.99, 'cancelled', '2024-02-04 13:00:00', NULL, '135 Maple St'), +(5, 399.99, 'pending', '2024-02-05 14:00:00', NULL, '246 Pine St'), +(6, 149.99, 'shipped', '2024-02-06 15:00:00', '2024-02-07 16:00:00', '789 Willow St'), +(7, 299.99, 'delivered', '2024-02-07 16:00:00', '2024-02-07 17:00:00', '369 Birch St'), +(8, 199.99, 'shipped', '2024-02-08 17:00:00', '2024-02-09 18:00:00', '258 Cedar St'), +(9, 599.99, 'delivered', '2024-02-09 18:00:00', '2024-02-10 19:00:00', '147 Spruce St'), +(10, 49.99, 'pending', '2024-02-10 19:00:00', NULL, '789 Aspen St'); +4.订单详细表: +CREATE TABLE OrderDetail ( + OrderDetailID INT AUTO_INCREMENT PRIMARY KEY, + OrderID INT NOT NULL, + ProductID INT NOT NULL, + UnitPrice DECIMAL(10, 2) NOT NULL, + Quantity INT NOT NULL, + FOREIGN KEY (OrderID) REFERENCES `Order` (OrderID), + FOREIGN KEY (ProductID) REFERENCES Product (ProductID) +); + +INSERT INTO OrderDetail (OrderID, ProductID, UnitPrice, Quantity) VALUES +(1, 1, 999.99, 1), +(2, 2, 599.99, 2), +(3, 3, 149.99, 1), +(4, 4, 79.99, 1), +(5, 6, 399.99, 1), +(6, 3, 149.99, 1), +(7, 7, 299.99, 1), +(8, 9, 199.99, 1), +(9, 10, 599.99, 1), +(10, 5, 49.99, 1); +5.购物车表: +CREATE TABLE ShoppingCart ( + ShoppingCartID INT AUTO_INCREMENT PRIMARY KEY, + UserID INT NOT NULL, + ProductID INT NOT NULL, + Quantity INT NOT NULL, + FOREIGN KEY (UserID) REFERENCES User (UserID), + FOREIGN KEY (ProductID) REFERENCES Product (ProductID) +); + +INSERT INTO ShoppingCart (UserID, ProductID, Quantity) VALUES +(1, 1, 1), +(1, 3, 2), +(2, 2, 1), +(2, 5, 3), +(3, 4, 1), +(3, 6, 2), +(4, 7, 1), +(4, 8, 1), +(5, 9, 1), +(5, 10, 1); +6.支付记录表: +CREATE TABLE PaymentRecord ( + PaymentID INT AUTO_INCREMENT PRIMARY KEY, + OrderID INT NOT NULL, + PaymentTime DATETIME NOT NULL, + PaymentMethod VARCHAR(50) NOT NULL, + PaymentStatus ENUM('paid', 'failed') NOT NULL, + Amount DECIMAL(10, 2) NOT NULL, + FOREIGN KEY (OrderID) REFERENCES `Order` (OrderID) +); + +INSERT INTO PaymentRecord (OrderID, PaymentTime, PaymentMethod, PaymentStatus, Amount) VALUES +(1, '2024-02-01 12:00:00', 'Credit Card', 'paid', 999.99), +(2, '2024-02-03 11:00:00', 'PayPal', 'paid', 1249.98), +(3, '2024-02-03 13:00:00', 'Debit Card', 'paid', 149.99), +(4, '2024-02-04 15:00:00', 'Credit Card', 'failed', 79.99), +(5, '2024-02-05 16:00:00', 'PayPal', 'paid', 399.99), +(6, '2024-02-07 18:00:00', 'Credit Card', 'paid', 149.99), +(7, '2024-02-07 19:00:00', 'Debit Card', 'paid', 299.99), +(8, '2024-02-09 19:00:00', 'PayPal', 'paid', 199.99), +(9, '2024-02-10 20:00:00', 'Credit Card', 'paid', 599.99), +(10, '2024-02-10 21:00:00', 'Debit Card', 'paid', 49.99); +7.评价记录表: +CREATE TABLE Review ( + ReviewID INT AUTO_INCREMENT PRIMARY KEY, + UserID INT NOT NULL, + ProductID INT NOT NULL, + ReviewTime DATETIME NOT NULL, + Content TEXT NOT NULL, + Rating INT CHECK (Rating BETWEEN 1 AND 5), + FOREIGN KEY (UserID) REFERENCES User (UserID), + FOREIGN KEY (ProductID) REFERENCES Product (ProductID) +); + +INSERT INTO Review (UserID, ProductID, ReviewTime, Content, Rating) +VALUES +(1, 1, NOW(), '这款笔记本电脑性能强大,非常好用!', 5), +(2, 2, NOW(), '手机外观精美,性能也很不错,值得购买。', 4), +(3, 3, NOW(), '耳机音质不错,降噪效果很好,但价格有点高。', 4), +(4, 4, NOW(), '手表功能强大,尤其适合运动使用,挺满意的。', 5), +(5, 5, NOW(), '电视画质清晰,音质也不错,适合家庭使用。', 4), +(6, 6, NOW(), '平板电脑轻便,适合出差旅行使用,价格适中。', 3), +(7, 7, NOW(), '游戏主机画面流畅,游戏体验很棒,非常推荐。', 5), +(8, 8, NOW(), '音响声音洪亮,携带方便,适合户外使用。', 4), +(9, 9, NOW(), '相机拍照效果很好,适合旅游使用。', 4), +(10, 10, NOW(), '键盘手感很好,适合长时间打字,推荐购买。', 5); + +8.物流表: +CREATE TABLE Logistics ( + LogisticsID INT AUTO_INCREMENT PRIMARY KEY, + OrderID INT NOT NULL, + Company VARCHAR(100) NOT NULL, + Status ENUM('pending', 'in_transit', 'delivered') NOT NULL, + EstimatedDeliveryTime DATETIME NOT NULL, + ActualDeliveryTime DATETIME, + DeliveryAddress TEXT, + FOREIGN KEY (OrderID) REFERENCES `Order` (OrderID) +); + +INSERT INTO Logistics (OrderID, Company, Status, ActualDeliveryTime, EstimatedDeliveryTime, DeliveryAddress) +VALUES +(1, '顺丰快递', 'in_transit', NULL, NOW(), '北京市朝阳区建国路100号'), +(2, '中通快递', 'delivered', NOW(), NOW(), '上海市浦东新区陆家嘴500号'), +(3, '申通快递', 'delivered', NOW(), NOW(), '广州市天河区体育东路200号'), +(4, '韵达快递', 'pending', NULL, NOW(), '深圳市福田区福田路300号'), +(5, '圆通快递', 'delivered', NOW(), NOW(), '北京市海淀区中关村大街400号'), +(6, '京东物流', 'in_transit', NULL, NOW(), '上海市徐汇区漕溪路500号'), +(7, '顺丰快递', 'pending', NULL, NOW(), '北京市东城区东直门外大街600号'), +(8, '中通快递', 'delivered', NOW(), NOW(), '广州市越秀区解放北路700号'), +(9, '申通快递', 'in_transit', NULL, NOW(), '深圳市南山区南海大道800号'), +(10, '圆通快递', 'pending', NULL, NOW(), '北京市西城区复兴门内大街900号'); + +9.商家表: +CREATE TABLE Merchant ( + MerchantID INT AUTO_INCREMENT PRIMARY KEY, + MerchantName VARCHAR(100) NOT NULL, + Address TEXT, + PhoneNumber VARCHAR(15) NOT NULL +); + +INSERT INTO Merchant (MerchantName, Address, PhoneNumber) +VALUES +('京东商城', '北京市朝阳区建国路100号', '010-12345678'), +('天猫旗舰店', '上海市浦东新区陆家嘴500号', '021-23456789'), +('苏宁易购', '广州市天河区体育东路200号', '020-34567890'), +('国美在线', '深圳市福田区福田路300号', '0755-45678901'), +('拼多多商家', '北京市海淀区中关村大街400号', '010-56789012'), +('小米商城', '上海市徐汇区漕溪路500号', '021-67890123'), +('华为商城', '北京市东城区东直门外大街600号', '010-78901234'), +('苹果商城', '广州市越秀区解放北路700号', '020-89012345'), +('三星商城', '深圳市南山区南海大道800号', '0755-90123456'), +('京东家电', '北京市西城区复兴门内大街900号', '010-23456789'); + +10.仓库表: +CREATE TABLE Warehouse ( + WarehouseID INT AUTO_INCREMENT PRIMARY KEY, + WarehouseName VARCHAR(100) NOT NULL, + Address TEXT NOT NULL, + Capacity INT NOT NULL, + CurrentStock INT NOT NULL CHECK (CurrentStock <= Capacity), + MerchantID INT NOT NULL, + FOREIGN KEY (MerchantID) REFERENCES Merchant (MerchantID) +); + +INSERT INTO Warehouse (WarehouseName, Address, PhoneNumber, MerchantID, Status, Capacity, CurrentStock) +VALUES +('京东仓库', '北京市朝阳区建国路100号', '010-12345678', 1, 'active', 5000, 3000), +('天猫仓库', '上海市浦东新区陆家嘴500号', '021-23456789', 2, 'active', 3000, 1500), +('苏宁仓库', '广州市天河区体育东路200号', '020-34567890', 3, 'inactive', 2000, 1000), +('国美仓库', '深圳市福田区福田路300号', '0755-45678901', 4, 'active', 4000, 2500), +('拼多多仓库', '北京市海淀区中关村大街400号', '010-56789012', 5, 'active', 3500, 2000), +('小米仓库', '上海市徐汇区漕溪路500号', '021-67890123', 6, 'inactive', 1500, 800), +('华为仓库', '北京市东城区东直门外大街600号', '010-78901234', 7, 'active', 4500, 3000), +('苹果仓库', '广州市越秀区解放北路700号', '020-89012345', 8, 'active', 5000, 3200), +('三星仓库', '深圳市南山区南海大道800号', '0755-90123456', 9, 'inactive', 2500, 1500), +('京东家电仓库', '北京市西城区复兴门内大街900号', '010-23456789', 10, 'active', 3000, 1800); + +1. 比较条件查询 +查询需求: +查询价格大于5000元的所有商品。 +查询销量大于100且库存数量小于50的商品。 + +查询脚本: + +-- 查询价格大于5000元的所有商品 +SELECT * FROM Product +WHERE Price > 5000; + +-- 查询销量大于100且库存数量小于50的商品 +SELECT * FROM Product +WHERE Sales > 100 AND StockQuantity < 50; + +2. 集合比较查询 +查询需求: +查询所有销量排名前10的商品名称。 +查询所有库存大于100且价格低于3000元的商品。 + +查询脚本: + +-- 查询所有销量排名前10的商品名称 +SELECT ProductName FROM Product +ORDER BY Sales DESC +LIMIT 10; + +-- 查询所有库存大于100且价格低于3000元的商品 +SELECT * FROM Product +WHERE StockQuantity > 100 +AND Price < 3000; + +3. 范围比较查询 +查询需求: +查询价格在1000到5000元之间的商品。 +查询创建时间在2023年1月1日到2023年12月31日之间的订单。 + +查询脚本: + +-- 查询价格在1000到5000元之间的商品 +SELECT * FROM Product +WHERE Price BETWEEN 1000 AND 5000; + +-- 查询创建时间在2023年1月1日到2023年12月31日之间的订单 +SELECT * FROM `Order` +WHERE CreationTime BETWEEN '2023-01-01' AND '2023-12-31'; + +4. 字符串相似比较查询 +查询需求: +查询商品名称中包含“iPhone”的所有商品。 +查询用户名中包含“admin”字符的所有用户。 + +查询脚本: + +-- 查询商品名称中包含“iPhone”的所有商品 +SELECT * FROM Product +WHERE ProductName LIKE '%iPhone%'; + +-- 查询用户名中包含“admin”字符的所有用户 +SELECT * FROM User +WHERE Username LIKE '%admin%'; + +5. 多表连接查询 +查询需求: +查询每个订单的用户名称、商品名称和订单总价。 +查询每个用户购买过的商品及其购买数量 +查询脚本: + +-- 查询每个订单的用户名称、商品名称和订单总价 +SELECT U.Username, P.ProductName, O.TotalPrice +FROM `Order` O +JOIN User U ON O.UserID = U.UserID +JOIN OrderDetail OD ON O.OrderID = OD.OrderID +JOIN Product P ON OD.ProductID = P.ProductID; + +-- 查询每个用户购买过的商品及其购买数量 +SELECT U.Username, P.ProductName, OD.Quantity +FROM User U +JOIN `Order` O ON U.UserID = O.UserID +JOIN OrderDetail OD ON O.OrderID = OD.OrderID +JOIN Product P ON OD.ProductID = P.ProductID; + +6. 嵌套查询 +查询需求: +查询销量大于所有商品的平均销量的商品。 +查询订单中总价大于所有订单的平均总价的订单。 + +查询脚本: + +-- 查询销量大于所有商品的平均销量的商品 +SELECT * FROM Product +WHERE Sales > (SELECT AVG(Sales) FROM Product); + +-- 查询订单中总价大于所有订单的平均总价的订单 +SELECT * FROM `Order` +WHERE TotalPrice > (SELECT AVG(TotalPrice) FROM `Order`); + +7. EXISTS查询 +查询需求: +查询所有有订单记录的用户。 +查询有评论记录的商品. + +查询脚本: + +-- 查询所有有订单记录的用户 +SELECT * FROM User +WHERE EXISTS (SELECT 1 FROM `Order` O WHERE O.UserID = User.UserID); + +-- 查询有评论记录的商品 +SELECT * FROM Product +WHERE EXISTS (SELECT 1 FROM Review R WHERE R.ProductID = Product.ProductID); + +*以上为必须有的查询 + +8. 聚合函数查询 +查询需求: +查询每个商品的总销量。 +查询所有订单的总支付金额. + +查询脚本: + +-- 查询每个商品的总销量 +SELECT P.ProductName, SUM(OD.Quantity) AS TotalSales +FROM OrderDetail OD +JOIN Product P ON OD.ProductID = P.ProductID +GROUP BY P.ProductName; + +-- 查询所有订单的总支付金额 +SELECT SUM(Amount) AS TotalPayment +FROM PaymentRecord; + +9. 排序查询 +查询需求: +查询销量从高到低的前5个商品。 +查询按订单创建时间排序的最新10个订单。 + +查询脚本: + +-- 查询销量从高到低的前5个商品 +SELECT * FROM Product +ORDER BY Sales DESC +LIMIT 5; + +-- 查询按订单创建时间排序的最新10个订单 +SELECT * FROM `Order` +ORDER BY CreationTime DESC +LIMIT 10; + +10. 分组查询 +查询需求: +查询每个用户的订单数量。 +查询每个商家在不同仓库的库存总数。 + +查询脚本: + +-- 查询每个用户的订单数量 +SELECT U.Username, COUNT(O.OrderID) AS OrderCount +FROM User U +JOIN `Order` O ON U.UserID = O.UserID +GROUP BY U.Username; + +-- 查询每个商家在不同仓库的库存总数 +SELECT M.MerchantName, W.WarehouseName, SUM(W.CurrentStock) AS TotalStock +FROM Warehouse W +JOIN Merchant M ON W.MerchantID = M.MerchantID +GROUP BY M.MerchantName, W.WarehouseName; + +11. 查询指定日期的订单 +查询需求: +查询2023年1月1日到2023年6月30日之间的订单。 +查询2024年12月20日之前支付完成的所有订单。 + +查询脚本: + +-- 查询2023年1月1日到2023年6月30日之间的订单 +SELECT * FROM `Order` +WHERE CreationTime BETWEEN '2023-01-01' AND '2023-06-30'; + +-- 查询2024年12月20日之前支付完成的所有订单 +SELECT * FROM `Order` +WHERE PaymentTime < '2024-12-20' AND OrderStatus = 'shipped'; + +12. 删除记录查询 +查询需求: +查询并删除销量低于50的商品。 +查询并删除库存为0的商品。 + +查询脚本: + +-- 查询并删除销量低于50的商品 +DELETE FROM Product +WHERE Sales < 50; + +-- 查询并删除库存为0的商品 +DELETE FROM Product +WHERE StockQuantity = 0; + +13. 检查表记录 +查询需求: +检查某商品是否已经有评论记录。 +检查某用户是否已经支付过订单。 + +查询脚本: + +-- 检查某商品是否已经有评论记录 +SELECT EXISTS (SELECT 1 FROM Review WHERE ProductID = 1) AS HasReviews; + +-- 检查某用户是否已经支付过订单 +SELECT EXISTS (SELECT 1 FROM PaymentRecord WHERE OrderID IN (SELECT OrderID FROM `Order` WHERE UserID = 1)) AS HasPaidOrders; +更新需求与更新脚本 +1. 更新商品价格 +需求:将价格低于3000元的所有商品的价格提升10%。 + +更新脚本: + +UPDATE Product +SET Price = Price * 1.1 +WHERE Price < 3000; + +2. 更新用户状态 +需求:将所有注册时间在2023年之前的用户账户状态设置为“inactive”。 + +更新脚本: + +UPDATE User +SET AccountStatus = 'inactive' +WHERE RegistrationTime < '2023-01-01'; + +3. 更新订单总价 +需求:将订单ID为1的订单总价更新为5000元。 + +更新脚本: + +UPDATE `Order` +SET TotalPrice = 5000 +WHERE OrderID = 1; + +4. 更新商品库存 +需求:将所有商品的库存数量增加20。 + +更新脚本: + +UPDATE Product +SET StockQuantity = StockQuantity + 20; +5. 更新商品状态 +需求:将所有库存量为0且上架状态为“listed”的商品的状态更新为“unlisted” + +更新脚本: + +UPDATE Product +SET Status = 'unlisted' +WHERE StockQuantity = 0 AND Status = 'listed'; + +6. 更新订单支付时间 +需求:将订单ID为10的订单支付时间更新为2024年1月1日。 + +更新脚本: + +UPDATE `Order` +SET PaymentTime = '2024-01-01' +WHERE OrderID = 10; + +7. 更新订单收货地址 +需求:将订单ID为5的收货地址更新为“北京市朝阳区建国路123号”。 + +更新脚本: + +UPDATE `Order` +SET DeliveryAddress = '北京市朝阳区建国路123号' +WHERE OrderID = 5; + +8. 更新评价记录评分 +需求:将商品ID为3的所有评价的评分更新为5分。 + +更新脚本: + +UPDATE Review +SET Rating = 5 +WHERE ProductID = 3; + +9. 更新商家联系电话 +需求:将商家ID为2的联系电话更新为“13900001111”。 + +更新脚本: + +UPDATE Merchant +SET PhoneNumber = '13900001111' +WHERE MerchantID = 2; + +10. 更新仓库状态 +需求:将仓库ID为4的仓库状态更新为“inactive”。 + +更新脚本: + +UPDATE Warehouse +SET Status = 'inactive' +WHERE WarehouseID = 4; + +删除需求与删除脚本 + +1. 删除价格低于1000元的商品 +需求:删除所有价格低于1000元的商品。 + +删除脚本: + +DELETE FROM Product +WHERE Price < 1000; + +2. 删除所有未支付的订单 +需求:删除所有支付状态为“failed”的订单。 + +删除脚本: + +DELETE FROM `Order` +WHERE OrderID IN (SELECT OrderID FROM PaymentRecord WHERE PaymentStatus = 'failed'); +3. 删除用户评论记录 +需求:删除所有用户ID为1的评论记录。 + +删除脚本: + +DELETE FROM Review +WHERE UserID = 1; + +4. 删除没有订单记录的用户 +需求:删除没有订单记录的所有用户。 + +删除脚本: + +DELETE FROM User +WHERE UserID NOT IN (SELECT DISTINCT UserID FROM `Order`); + +5. 删除已取消的订单 +需求:删除所有订单状态为“cancelled”的订单。 + +删除脚本: + +DELETE FROM `Order` +WHERE OrderStatus = 'cancelled'; + +6. 删除已过期的商品 +需求:删除所有下架状态为“unlisted”的商品。 + +删除脚本: + +DELETE FROM Product +WHERE Status = 'unlisted'; + +7. 删除无效支付记录 +需求:删除所有支付状态为“failed”的支付记录。 + +删除脚本: + +DELETE FROM PaymentRecord +WHERE PaymentStatus = 'failed'; + +8. 删除库存为0的商品 +需求:删除所有库存数量为0的商品。 + +删除脚本: + +DELETE FROM Product +WHERE StockQuantity = 0; + +9. 删除不再使用的仓库 +需求:删除所有状态为“inactive”的仓库。 + +删除脚本: + +DELETE FROM Warehouse +WHERE Status = 'inactive'; + +10. 删除所有物流记录 +需求:删除所有物流状态为“delivered”的记录。 + +删除脚本: + +DELETE FROM Logistics +WHERE Status = 'delivered'; +1. 用户订单视图 +需求:展示用户及其订单的详细信息,包括用户ID、用户名、订单ID、订单总价、订单状态、创建时间等。 +视图脚本: + +CREATE VIEW UserOrders AS +SELECT u.UserID, u.Username, o.OrderID, o.TotalPrice, o.OrderStatus, o.CreationTime +FROM User u +JOIN `Order` o ON u.UserID = o.UserID; +2. 商品与订单详情视图 +需求:展示商品名称、商品单价、商品数量及订单总价的汇总信息,便于了解每个商品的销售情况。 +视图脚本: + +CREATE VIEW ProductOrderDetails AS +SELECT p.ProductName, od.UnitPrice, od.Quantity, o.TotalPrice +FROM Product p +JOIN OrderDetail od ON p.ProductID = od.ProductID +JOIN `Order` o ON od.OrderID = o.OrderID; +3. 商品库存与销量视图 +需求:展示商品ID、商品名称、库存数量以及销量,以便商家能够及时了解商品库存与销售情况。 +视图脚本: + +CREATE VIEW ProductInventorySales AS +SELECT p.ProductID, p.ProductName, p.StockQuantity, p.Sales +FROM Product p; +4. 用户支付记录视图 +需求:展示用户的支付记录,包括支付时间、支付金额、支付方式和支付状态。 +视图脚本: + +CREATE VIEW UserPaymentHistory AS +SELECT u.UserID, u.Username, pr.PaymentTime, pr.Amount, pr.PaymentMethod, pr.PaymentStatus +FROM User u +JOIN PaymentRecord pr ON u.UserID = pr.UserID; +5. 订单物流状态视图 +需求:展示订单的物流状态,包括订单ID、物流公司、物流状态、预计到达时间和实际到达时间。 +视图脚本: + +CREATE VIEW OrderLogisticsStatus AS +SELECT o.OrderID, l.Company AS LogisticsCompany, l.Status AS LogisticsStatus, + l.EstimatedDeliveryTime, l.ActualDeliveryTime +FROM `Order` o +JOIN Logistics l ON o.OrderID = l.OrderID; +6. 商家商品销售情况视图 +需求:展示商家ID、商家名称、商品名称、商品销量和商品价格,便于商家查看销售情况。 +视图脚本: + +CREATE VIEW MerchantProductSales AS +SELECT m.MerchantID, m.MerchantName, p.ProductName, p.Sales, p.Price +FROM Merchant m +JOIN Product p ON m.MerchantID = p.MerchantID; +7. 商品评价视图 +需求:展示商品名称、用户ID、用户评价内容、评分及评价时间,方便查看商品的评价情况。 +视图脚本: + +CREATE VIEW ProductReviews AS +SELECT p.ProductName, r.UserID, r.Content AS ReviewContent, r.Rating, r.ReviewTime +FROM Product p +JOIN Review r ON p.ProductID = r.ProductID; +8. 仓库库存状态视图 +需求:展示仓库ID、仓库名称、库存容量、当前库存量以及仓库状态,以便商家查看库存状态。 +视图脚本: + +CREATE VIEW WarehouseInventoryStatus AS +SELECT w.WarehouseID, w.WarehouseName, w.Capacity, w.CurrentStock, w.Status +FROM Warehouse w; +用户表的用户名索引:CREATE INDEX idx_username ON User (Username); +订单表的用户ID索引:CREATE INDEX idx_user_id ON `Order` (UserID); +订单表的订单状态索引:CREATE INDEX idx_order_status ON `Order` (OrderStatus); +订单详情表的订单ID索引CREATE INDEX idx_order_id ON OrderDetail (OrderID); +商品表的价格索引CREATE INDEX idx_price ON Product (Price); +购物车表的用户ID和商品ID复合索引CREATE INDEX idx_user_product ON ShoppingCart (UserID, ProductID); +支付记录表的订单ID索引CREATE INDEX idx_order_payment_id ON PaymentRecord (OrderID); + 评价记录表的商品ID索引CREATE INDEX idx_product_review_id ON Review (ProductID); +商家表的商家名称索引CREATE INDEX idx_merchant_name ON Merchant (MerchantName); +物流表的订单ID索引CREATE INDEX idx_logistics_order_id ON Logistics (OrderID); +仓库表的仓库状态索引CREATE INDEX idx_warehouse_status ON Warehouse (Status); + 商品表的商品名称索引CREATE INDEX idx_product_name ON Product (ProductName); + 用户表的邮箱索引CREATE INDEX idx_email ON User (Email); +订单详情表的商品ID和订单ID复合索引CREATE INDEX idx_product_order_detail ON OrderDetail (ProductID, OrderID); +支付记录表的支付状态索引CREATE INDEX idx_payment_status ON PaymentRecord (PaymentStatus); +商品表的销量索引CREATE INDEX idx_sales ON Product (Sales); + 仓库表的生产商ID索引CREATE INDEX idx_merchant_warehouse_id ON Warehouse (MerchantID); +物流表的物流状态索引CREATE INDEX idx_logistics_status ON Logistics (Status); +用户表的注册时间索引CREATE INDEX idx_registration_time ON User (RegistrationTime); +1. 存储过程:根据用户ID查询用户的所有订单 +需求:根据用户的ID查询该用户所有的订单及相关信息。 +存储过程脚本: + +DELIMITER $$ + +CREATE PROCEDURE GetUserOrders(IN userId INT) +BEGIN + SELECT o.OrderID, o.TotalPrice, o.OrderStatus, o.CreationTime, o.PaymentTime, o.DeliveryAddress + FROM `Order` o + WHERE o.UserID = userId; +END $$ + +DELIMITER ; +2. 存储过程:更新商品价格 +需求:根据商品ID更新指定商品的价格。 +存储过程脚本: + +DELIMITER $$ + +CREATE PROCEDURE UpdateProductPrice(IN productId INT, IN newPrice DECIMAL(10, 2)) +BEGIN + UPDATE Product + SET Price = newPrice + WHERE ProductID = productId; +END $$ + +DELIMITER ; +3. 存储过程:根据订单ID查询订单详情 +需求:根据订单ID查询该订单的所有商品及对应的数量和价格。 +存储过程脚本: + +DELIMITER $$ + +CREATE PROCEDURE GetOrderDetails(IN orderId INT) +BEGIN + SELECT od.OrderDetailID, p.ProductName, od.Quantity, od.UnitPrice + FROM OrderDetail od + JOIN Product p ON od.ProductID = p.ProductID + WHERE od.OrderID = orderId; +END $$ + +DELIMITER ; +4. 存储过程:添加新的商品到购物车 +需求:根据用户ID和商品ID将商品添加到用户的购物车中。 +存储过程脚本: + +DELIMITER $$ + +CREATE PROCEDURE AddProductToCart(IN userId INT, IN productId INT, IN quantity INT) +BEGIN + DECLARE cartExist INT; + + -- 检查商品是否已经在购物车中 + SELECT COUNT(*) INTO cartExist + FROM ShoppingCart + WHERE UserID = userId AND ProductID = productId; + + IF cartExist > 0 THEN + -- 如果商品已存在于购物车中,更新数量 + UPDATE ShoppingCart + SET Quantity = Quantity + quantity + WHERE UserID = userId AND ProductID = productId; + ELSE + -- 如果商品不在购物车中,插入新记录 + INSERT INTO ShoppingCart (UserID, ProductID, Quantity) + VALUES (userId, productId, quantity); + END IF; +END $$ + +DELIMITER ; +5. 存储过程:删除指定订单的所有订单详情 +需求:根据订单ID删除该订单下的所有订单详情记录。 +存储过程脚本: + +DELIMITER $$ + +CREATE PROCEDURE DeleteOrderDetails(IN orderId INT) +BEGIN + DELETE FROM OrderDetail + WHERE OrderID = orderId; +END $$ + +DELIMITER ; +1. 触发器:当订单状态更新为“已支付”时,自动更新订单的支付时间 +需求:当订单状态更新为“已支付”时,自动将当前时间记录到支付时间字段。 +触发器脚本: + +DELIMITER $$ + +CREATE TRIGGER UpdatePaymentTimeBeforeUpdate +BEFORE UPDATE ON `Order` +FOR EACH ROW +BEGIN + IF NEW.OrderStatus = 'shipped' AND OLD.OrderStatus != 'shipped' THEN + SET NEW.PaymentTime = NOW(); + END IF; +END $$ + +DELIMITER ; +2. 触发器:当商品库存数量变化时,自动记录库存变动日志 +需求:当商品的库存数量发生变化时,记录库存变动日志。 +触发器脚本: + +DELIMITER $$ + +CREATE TRIGGER LogInventoryChangeAfterUpdate +AFTER UPDATE ON Product +FOR EACH ROW +BEGIN + IF OLD.StockQuantity != NEW.StockQuantity THEN + INSERT INTO InventoryLog (ProductID, OldQuantity, NewQuantity, ChangeTime) + VALUES (NEW.ProductID, OLD.StockQuantity, NEW.StockQuantity, NOW()); + END IF; +END $$ + +DELIMITER ; +3. 触发器:当订单删除时,自动删除该订单的订单详情 +需求:当订单被删除时,自动删除该订单下的所有订单详情。 +触发器脚本: + +DELIMITER $$ + +CREATE TRIGGER DeleteOrderDetailsBeforeDelete +BEFORE DELETE ON `Order` +FOR EACH ROW +BEGIN + DELETE FROM OrderDetail WHERE OrderID = OLD.OrderID; +END $$ + +DELIMITER ; +4. 触发器:当评价记录插入时,自动更新商品的评分 +需求:当商品的评价记录插入时,自动更新该商品的平均评分。 +触发器脚本: + +DELIMITER $$ + +CREATE TRIGGER UpdateProductRatingAfterInsert +AFTER INSERT ON Review +FOR EACH ROW +BEGIN + DECLARE avgRating DECIMAL(3, 2); + + -- 计算商品的平均评分 + SELECT AVG(Rating) INTO avgRating + FROM Review + WHERE ProductID = NEW.ProductID; + + -- 更新商品的评分 + UPDATE Product + SET Rating = avgRating + WHERE ProductID = NEW.ProductID; +END $$ + +DELIMITER ; +5. 触发器:当用户删除时,删除该用户的所有购物车记录 +需求:当用户删除时,自动删除该用户在购物车中的所有记录。 +触发器脚本: + +DELIMITER $$ + +CREATE TRIGGER DeleteShoppingCartBeforeDelete +BEFORE DELETE ON User +FOR EACH ROW +BEGIN + DELETE FROM ShoppingCart WHERE UserID = OLD.UserID; +END $$ + +DELIMITER ; +设计: 用户角色及权限设计 +用户角色 +管理员(Admin) + +拥有对所有表的完全访问权限,包括增、删、改、查。 +能够管理用户、订单、商品等敏感数据。 +商家(Merchant) + +仅能访问与自己商品相关的数据。 +可以查看和修改自己上传的商品、查看和处理自己的订单。 +普通用户(Customer) + +仅能访问与自己相关的数据。 +可以查看商品、下订单、查看自己的订单和购物车,但不能修改商品或管理订单。 +权限分配 +管理员:对所有数据库对象(表、视图、存储过程等)拥有所有权限。 +商家:只能访问自己上传的商品、订单等与自己相关的数据。 +普通用户:只能访问自己的个人信息、购物车、订单等数据。 + +实现: +1. 创建角色 + +-- 创建管理员角色 +CREATE ROLE Admin; + +-- 创建商家角色 +CREATE ROLE Merchant; + +-- 创建普通用户角色 +CREATE ROLE Customer; + +2. 创建用户并分配角色 + +-- 创建管理员用户 +CREATE USER 'admin_user'@'localhost' IDENTIFIED BY 'admin_password'; +GRANT Admin TO 'admin_user'@'localhost'; + +-- 创建商家用户 +CREATE USER 'merchant_user'@'localhost' IDENTIFIED BY 'merchant_password'; +GRANT Merchant TO 'merchant_user'@'localhost'; + +-- 创建普通用户 +CREATE USER 'customer_user'@'localhost' IDENTIFIED BY 'customer_password'; +GRANT Customer TO 'customer_user'@'localhost'; + +3. 分配权限 +管理员权限:管理员具有所有权限,不限表、视图、存储过程等。 + +GRANT ALL PRIVILEGES ON *.* TO 'admin_user'@'localhost' WITH GRANT OPTION; + +商家权限:商家可以对与自己相关的表(商品、订单等)进行操作。假设商家的商品和订单有 MerchantID 字段与商家一一对应,商家只能访问自己相关的商品和订单。 + +-- 商家对商品表的权限,仅限于自己上传的商品 +GRANT SELECT, INSERT, UPDATE ON Product TO 'merchant_user'@'localhost' + WHERE MerchantID = 'merchant_user'; + +-- 商家对订单表的权限,仅限于自己的订单 +GRANT SELECT, UPDATE ON `Order` TO 'merchant_user'@'localhost' + WHERE UserID IN (SELECT UserID FROM User WHERE UserType = 'merchant'); + +-- 商家对订单详情表的权限,仅限于自己的订单 +GRANT SELECT, INSERT, UPDATE ON OrderDetail TO 'merchant_user'@'localhost' + WHERE OrderID IN (SELECT OrderID FROM `Order` WHERE UserID = 'merchant_user'); +普通用户权限:普通用户只能查看和操作自己相关的数据,如个人信息、购物车、订单等。 + +-- 普通用户对商品表的权限(查看商品信息) +GRANT SELECT ON Product TO 'customer_user'@'localhost'; + +-- 普通用户对订单表的权限,仅限于自己的订单 +GRANT SELECT, INSERT, UPDATE ON `Order` TO 'customer_user'@'localhost' + WHERE UserID = 'customer_user'; + +-- 普通用户对购物车表的权限,仅限于自己的购物车 +GRANT SELECT, INSERT, DELETE ON ShoppingCart TO 'customer_user'@'localhost' + WHERE UserID = 'customer_user'; + +3. 限制对敏感数据的访问 +为防止普通用户和商家访问不应该有权限的敏感数据,我们可以通过视图和存储过程来限制用户的直接访问。 + +创建视图:商家只能查看自己的商品 + +CREATE VIEW MerchantProducts AS +SELECT ProductID, ProductName, Price, Status, StockQuantity +FROM Product +WHERE MerchantID = CURRENT_USER(); + +-- 商家查看商品时只能使用视图 +GRANT SELECT ON MerchantProducts TO 'merchant_user'@'localhost'; +创建存储过程:商家只能查看自己的订单 + +DELIMITER $$ + +CREATE PROCEDURE GetMerchantOrders() +BEGIN + SELECT o.OrderID, o.UserID, o.TotalPrice, o.OrderStatus + FROM `Order` o + WHERE o.UserID = (SELECT UserID FROM User WHERE Username = CURRENT_USER()); +END $$ + +DELIMITER ; + +-- 商家只能通过存储过程查看订单 +GRANT EXECUTE ON PROCEDURE GetMerchantOrders TO 'merchant_user'@'localhost'; +创建视图:普通用户只能查看自己的订单和购物车 + +CREATE VIEW CustomerOrders AS +SELECT o.OrderID, o.TotalPrice, o.OrderStatus, o.CreationTime +FROM `Order` o +WHERE o.UserID = (SELECT UserID FROM User WHERE Username = CURRENT_USER()); + +CREATE VIEW CustomerShoppingCart AS +SELECT sc.ProductID, sc.Quantity +FROM ShoppingCart sc +WHERE sc.UserID = (SELECT UserID FROM User WHERE Username = CURRENT_USER()); + +-- 普通用户只能通过视图查看自己的订单和购物车 +GRANT SELECT ON CustomerOrders TO 'customer_user'@'localhost'; +GRANT SELECT ON CustomerShoppingCart TO 'customer_user'@'localhost'; + +4. 撤销权限 +如果需要撤销某个用户的权限,使用以下语法: + +-- 撤销商家对商品表的权限 +REVOKE SELECT, INSERT, UPDATE ON Product FROM 'merchant_user'@'localhost'; + +-- 撤销普通用户对订单表的权限 +REVOKE SELECT, INSERT, UPDATE ON `Order` FROM 'customer_user'@'localhost'; + +import mysql.connector +from mysql.connector import Error + +# 连接到数据库 +def create_connection(): + try: + connection = mysql.connector.connect( + host='localhost', + user='root', # 数据库用户名 + password='password', # 数据库密码 + database='shop_db' # 数据库名称 + ) + if connection.is_connected(): + print("连接到数据库成功") + return connection + except Error as e: + print("无法连接到数据库:", e) + return None + + +# 关闭数据库连接 +def close_connection(connection): + if connection: + connection.close() + print("数据库连接已关闭") + + +# 添加商品 +def add_product(product_name, category_id, description, price, status, stock_quantity): + try: + connection = create_connection() + cursor = connection.cursor() + query = """INSERT INTO Product (ProductName, CategoryID, Description, Price, Status, StockQuantity) + VALUES (%s, %s, %s, %s, %s, %s)""" + cursor.execute(query, (product_name, category_id, description, price, status, stock_quantity)) + connection.commit() + print(f"商品 '{product_name}' 添加成功") + except Error as e: + print(f"添加商品失败: {e}") + finally: + close_connection(connection) + + +# 删除商品 +def delete_product(product_id): + try: + connection = create_connection() + cursor = connection.cursor() + query = "DELETE FROM Product WHERE ProductID = %s" + cursor.execute(query, (product_id,)) + connection.commit() + print(f"商品ID {product_id} 删除成功") + except Error as e: + print(f"删除商品失败: {e}") + finally: + close_connection(connection) + + +# 更新商品价格 +def update_product_price(product_id, new_price): + try: + connection = create_connection() + cursor = connection.cursor() + query = "UPDATE Product SET Price = %s WHERE ProductID = %s" + cursor.execute(query, (new_price, product_id)) + connection.commit() + print(f"商品ID {product_id} 价格更新为 {new_price}") + except Error as e: + print(f"更新商品价格失败: {e}") + finally: + close_connection(connection) + + +# 查询商品详情 +def get_product_details(product_id): + try: + connection = create_connection() + cursor = connection.cursor() + query = "SELECT * FROM Product WHERE ProductID = %s" + cursor.execute(query, (product_id,)) + product = cursor.fetchone() + if product: + print("商品详情:", product) + else: + print(f"未找到商品ID {product_id}") + except Error as e: + print(f"查询商品失败: {e}") + finally: + close_connection(connection) + + +# 查询商家商品(通过视图) +def get_merchant_products(): + try: + connection = create_connection() + cursor = connection.cursor() + query = "SELECT * FROM MerchantProducts" # 通过视图查询商家的商品 + cursor.execute(query) + products = cursor.fetchall() + for product in products: + print("商品ID:", product[0], "商品名称:", product[1]) + except Error as e: + print(f"查询商家商品失败: {e}") + finally: + close_connection(connection) + + +# 执行存储过程(例如获取商家订单) +def get_merchant_orders(): + try: + connection = create_connection() + cursor = connection.cursor() + cursor.callproc('GetMerchantOrders') # 调用存储过程 + for result in cursor.stored_results(): + orders = result.fetchall() + for order in orders: + print(f"订单ID: {order[0]}, 用户ID: {order[1]}, 总价: {order[2]}") + except Error as e: + print(f"查询商家订单失败: {e}") + finally: + close_connection(connection) + + +# 示例:查询商品详情(商家查看自己的商品) +get_product_details(1) + +# 示例:增加商品 +add_product("新商品", 1, "新商品描述", 99.99, "listed", 100) + +# 示例:更新商品价格 +update_product_price(1, 199.99) + +# 示例:删除商品 +delete_product(1) + +# 示例:查询商家商品 +get_merchant_products() + +# 示例:查询商家订单 +get_merchant_orders() +