数据库方向开发日志-Week1

BACKEND TODO:

  1. 数据表设计及初始化
  2. 数据库操作轮子重构

我们根据实际需求设计了数据表及字段,并规范了表之间的关系,编写了数据库初始化文件db_init.sql;数据库操作泽同学手中有自己写的轮子,但由于基于python2.7因此要对其先进行语法重构。


阶段成果记录:

1. 数据表设计及初始化

Users记录用户信息,Problems表记录题目信息,WriteUp表记录题解信息,Record表记录提交记录,其中Users、Problems表与WriteUp、Record表是一对多(ER图略),其余表相互独立。所有表id字段主键自增,create_time及update_time采用datetime数据类型。
关于提交结果判断还有培欣的bitmap神奇操作,但考虑到逻辑上的清晰故仍使用Record表。

Users:

id username password email points gender create_time update_time
0 dubhe 85b2f42582a1606d79a8741d3f26e595 [email protected] 0 M 2018-10-25-8:53:10 2018-10-26-8:53:10

Problems:

id name tag flag content points create-time update-time
0 Web Puzzle 01 web flag{dubhe_best} .... 10 2018-10-25-8:53:10 2018-10-26-8:53:10

WriteUp:

id uid pid content create-time update-time
0 0 0 ... 2018-10-25-8:53:10 2018-10-26-8:53:10

Record:

id uid pid state create_time update_time
0 0 0 0 2018-10-25-8:53:10 2018-10-25-8:53:10

db_init.sql代码:

数据库初始化文件,Luty先写了基本的创表和初始数据插入,泽龙用phpadmin重构了一下,规范了格式。

-- phpMyAdmin SQL Dump
-- version 4.8.2
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: Oct 28, 2018 at 07:19 PM
-- Server version: 5.7.21
-- PHP Version: 7.2.7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

CREATE DATABASE IF NOT EXISTS CTF;
USE CTF;
--
-- Database: `CTF`
--

-- --------------------------------------------------------

--
-- Table structure for table `Problems`
--

CREATE TABLE `Problems` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL COMMENT '题目名称',
  `tag` varchar(255) NOT NULL COMMENT '题目分类',
  `flag` varchar(255) NOT NULL,
  `content` text NOT NULL COMMENT '题目描述',
  `points` float(11,2) NOT NULL COMMENT '题目分数(两位小数)',
  `create_time` datetime NOT NULL,
  `update_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `Problems`
--

INSERT INTO `Problems` (`id`, `name`, `tag`, `flag`, `content`, `points`, `create_time`, `update_time`) VALUES
(1, 'Web Puzzle 01', 'web', 'flag{dubhe_best}', '[email protected]', 10.00, '2018-10-26 21:58:38', '2018-10-26 21:58:38');

-- --------------------------------------------------------

--
-- Table structure for table `Record`
--

CREATE TABLE `Record` (
  `id` int(11) NOT NULL,
  `uid` int(11) NOT NULL COMMENT '提交用户',
  `pid` int(11) NOT NULL COMMENT '提交问题',
  `state` int(11) NOT NULL COMMENT '提交结果',
  `create_time` datetime NOT NULL,
  `update_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `Record`
--

INSERT INTO `Record` (`id`, `uid`, `pid`, `state`, `create_time`, `update_time`) VALUES
(1, 0, 0, 0, '2018-10-26 21:58:38', '2018-10-26 21:58:38');

-- --------------------------------------------------------

--
-- Table structure for table `Users`
--

CREATE TABLE `Users` (
  `id` int(11) NOT NULL,
  `username` varchar(255) NOT NULL COMMENT '用户名',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `email` varchar(255) NOT NULL COMMENT '电子邮箱',
  `points` float(11,2) NOT NULL COMMENT '获得分数(两位小数)',
  `gender` varchar(255) NOT NULL COMMENT '性别',
  `create_time` datetime NOT NULL,
  `update_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `Users`
--

INSERT INTO `Users` (`id`, `username`, `password`, `email`, `points`, `gender`, `create_time`, `update_time`) VALUES
(1, 'duhbe', '85b2f42582a1606d79a8741d3f26e595', '[email protected]', 10.00, 'M', '2018-10-26 21:58:38', '2018-10-26 21:58:38'),
(2, 'a', 'a', 'a', 123.00, 'a', '2018-10-26 00:00:00', '2018-10-26 00:00:00');

-- --------------------------------------------------------

--
-- Table structure for table `WriteUp`
--

CREATE TABLE `WriteUp` (
  `id` int(11) NOT NULL,
  `uid` int(11) NOT NULL COMMENT '所属用户',
  `pid` int(11) NOT NULL COMMENT '所属题目',
  `content` text NOT NULL,
  `create_time` datetime NOT NULL,
  `update_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `WriteUp`
--

INSERT INTO `WriteUp` (`id`, `uid`, `pid`, `content`, `create_time`, `update_time`) VALUES
(1, 0, 0, 'this is a WriteUp', '2018-10-26 21:58:38', '2018-10-26 21:58:38');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `Problems`
--
ALTER TABLE `Problems`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `Record`
--
ALTER TABLE `Record`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `Users`
--
ALTER TABLE `Users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `username` (`username`),
  ADD UNIQUE KEY `email` (`email`);

--
-- Indexes for table `WriteUp`
--
ALTER TABLE `WriteUp`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `Problems`
--
ALTER TABLE `Problems`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

--
-- AUTO_INCREMENT for table `Record`
--
ALTER TABLE `Record`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

--
-- AUTO_INCREMENT for table `Users`
--
ALTER TABLE `Users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

--
-- AUTO_INCREMENT for table `WriteUp`
--
ALTER TABLE `WriteUp`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

2. 后端轮子重构

上述是Luty写的,写的很有水平,我现在有些害怕。
原来的轮子是用Python2.7编写的,所以需要重构

数据库模块重构

原来使用的是MySQLdb但这个令人头疼的包,他居然不与时俱进!!(不与时俱进就要被淘汰啊)。所以他就被抛弃了。(可怜)

MySQLdb 语法解释

原来的MySQLdb是相当的麻烦,你们可以从MySQLdb这里可以看出来。

pymysql 解释

既然MySQLdb是如此的麻烦,那么pymysql是不是简单些呢? 巧了 ,pymysql甚至更加的麻烦pymysql,从这里看的出来真不巧啊。所以我们需要再次封装

那他有什么与MySQLdb有什么不一样呢?
据我所知,一个是提交代码需要用commit(),如果执行错误还要rollback(),这可是前任不需要的啊。真矫情!

其他重构细节

1.原来我所使用的输入输出库是第三方库,被改良过的,可以输出各种颜色(真强),现在使用服务器上,这东西怕是用不了了。就改成了print()了。
2.原来我的轮子使用的比较繁琐,需要先start(),在执行,在stop(),在原本的情况下,Luty可能会嫌弃我的轮子,所以我改良了一下,就不用start() stop()了。

这里贴出源码

import pymysql

class Mysql:
    """
        Mysql库用法x
            1.初始化数据库类
            2.执行操作
    """
    def __init__(self, user, password, host, port, db):
        self.__user = user
        self.__password = password
        self.__host = host
        self.__port = port
        self.__db = db
        # 初始化各种变量

    def start(self):
        try:
            self.__conn = pymysql.connect(
                host=self.__host,
                user=self.__user,
                passwd=self.__password,
                port=self.__port,
                db=self.__db,
                charset='utf8mb4',  # 数据库编码类型
            )
            self.__cursor = self.__conn.cursor()
            return True  # 调用时判断是否执行成功
        except Exception as e:
            print(e)
            return False

    def stop(self):
        self.__cursor.close()
        self.__conn.close()

    def query(self, query):  # 执行query语句,返回所有结果
            try:
                self.start()
                self.__cursor.execute(query)
                self.__conn.commit()
                self.stop()
                return self.__cursor.fetchall()
            except Exception as e:
                self.__conn.rollback()
                print(e)
                return False
            finally:
                pass

    def execute(self, query):  # 用于执行不需要返回值的语句,返回True 或 False
        _bool = True  # 用于记录语句是否执行成功
        try:
            self.start()
            self.__cursor.execute(query)
            self.__conn.commit()
            self.stop()
        except Exception as e:
            print(e)
            self.__conn.rollback()
            return False
        finally:
            return _bool

    def insert(self, table, data):
        # 数据库插入操作 这里如果有引号请自己在data中转义 无法自动判断
        name = []
        value = []
        for key in data:
            name.append('`' + str(key) + '`')  # 这里的str是防止输入的是数字
            value.append(str(data[key]))
        query = 'insert into `' + table + \
            '` (' + ','.join(name) + ') values (' + ','.join(value) + ')'
        return self.execute(query)

    def delete(self, table, where='1=2'):
        # 删除行 一定不要把where写成永远为真的值
        query = 'delete from `' + table + '` where ' + where
        return self.execute(query)

    def update(self, table, data, where='1=2'):
        # 更新行 记得如果是字符串单引号转义
        sets = []
        for key in data:
            sets.append('`' + str(key) + '`=' + str(data[key]))
        query = 'update `' + table + '` set ' + ','.join(sets) + ' where ' + where
        return self.execute(query)

    def select(self, table, key, where, suffix=''):
        # select行 suffix是指如果要查询order by ,union之类的东西写的
        if len(key) == 0:
            key = ['*']
        value = ','.join(key)
        query = 'select ' + value + ' from `' + table + '` where ' + where + ' ' + suffix
        return self.query(query)

请忍受我的代码,别开枪打死我。


你可能感兴趣的:(数据库方向开发日志-Week1)