基于Python的数据库实现

基于Python的数据库实现 1,需求分析 1,1 概述 从底层做起,实现数据库的组织,存储,检索,更新和索引等功能, 1,2 基本功能 设计特定的数据结构

本文包含相关资料包-----> 点击直达获取<-------

基于Python的数据库实现

1.需求分析

1.1 概述

从底层做起,实现数据库的组织、存储、检索、更新和索引等功能。

1.2 基本功能

  • 设计特定的数据结构,用于存储数据表、视图、索引三种数据库对象的元数据信息,建立数据库系统的数据字典

  • 设计特定的数据结构,用于存储数据表中的数据

  • 设计特定的数据结构,用于存储索引数据

  • 设计特定的数据结构,分别用于存储用户和访问权限的信息

  • 输入“help database”命令,输出所有数据表、视图和索引的信息,同时显示其对象类型;输入“help table 表名”命令,输出数据表中所有属性的详细信息;输入“help view 视图名”命令,输出视图的定义语句;输入“help index 索引名”命令,输出索引的详细信息

  • 解析CREATE、SELECT、INSERT、DELETE、UPDATE等SQL语句的内容;检查SQL语句中的语法错误和语义错误

  • 执行CREATE语句,创建数据表、视图、索引三种数据库对象;创建数据表时需要包含主码外码、唯一性约束、非空约束等完整性约束的定义

  • 执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUP BY、HAVING和ORDER BY子句,需要支持5种聚集函数

  • 执行INSERT、DELETE和UPDATE语句,更新数据表的内容;更新过程中需要检查更新后的数据表是否会违反参照完整性约束。如果是,则提示违反哪一条完整性约束,并拒绝执行更新操作;如果否,提示数据表更新成功,并说明插入、删除或修改了几个元组

  • 当数据表的内容更新后,根据索引的定义,自动更新索引表的内容

  • 在有索引的数据表上执行查询语句时,首先利用索引找到满足条件的元组指针,然后通过指针到数据表中取出相应的元组

  • 执行GRANT语句,为用户授予对某数据库对象的SELECT、INSERT、DELETE、UPDATE等权限;执行REVOKE语句,收回上述权限

  • 用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新等操作,并给出提示信息

  • 将SELECT语句转化为关系代数表达式,再利用查询优化算法对关系代数表达式进行优化,输出优化后的关系代数表达式或SELECT语句

1.3 系统需求

  • 开发语言:Python

  • 开发工具:Pycharm

2.概要设计说明

2.1 数据文件存储

设置system库,table_information库,view库为系统初始化后建立的初始数据库。文件使用excel存储。

2.2 模块功能及描述

2.1.1 run函数模块

run函数模块是整个系统的入口,本模块的主要功能是初始化用户,调用各模块,处理用户输入,实现数据库管理功能。

2.1.2 用户验证及登录模块

本模块功能是进行用户的登录认证。

2.1.3 创建表模块

根据标准 SQL 语言将输入语句进行分割,获得表名,各个属性名,属性类型,约束条件等内容,再进行表的创建。

2.1.4 创建视图模块

本模块通过 CREATE VIEW VIEW_NAME AS SELECT …语句来创建视图,将存储视图和对应的语句。

2.1.5 插入数据模块

将用户输入的数据存入相应的表中并进行约束检查。

2.1.6 更新数据模块

根据用户的 WHERE 条件更新符合条件的元组并进行约束检查。

2.1.7 查询数据模块

根据用户的查询条件进行查询。

2.1.8 删除数据模块

根据用户的 WHERE 条件删除符合条件的元组。

2.1.9 帮助模块

  • HELP DATABASE 可查看当前数据库下的所有的表,视图信息

  • help table 表名可输出数据表中所有属性的详细信息

  • 输入“help view 视图名”命令,输出视图的定义语句

  • 输入“help index 索引名”命令,输出索引的详细信息

2.1.10 授权与权限收回模块

通过grant和revork实现用户对表和视图的 CREATE、DELETE、UPDATE、INSERT 四种操作的权限授予与收回。

2.1.11 索引建立和更新模块

使用create语句建立索引,在内容更新后更新索引。

2.3 模块调用图

3.详细设计说明

3.1 环境依赖

本程序用到的库:

``python from openpyxl import * import os import re from index import * from prettytable import PrettyTable import hashlib import bisect import Queue ```

3.2 数据存储

数据库的数据使用xlsx格式存储,每一个文件对应一个数据库,工作簿对应库中的表,表结构和文件结构对应。

索引使用文本存储dict。

使用openpyxl库进行文件内容的操作。

数据库示例:

3.3 run函数的功能

​```python * 程序初始化 * 打印欢迎语句 * 处理用户登录与认证 * 处理帮助命令和退出命令

def run(): Initialization() welcome() login() while True: command = get_command() #print command if command == 'quit' or command == 'exit': print("[🍻] Thanks for using L-DBMS. Bye~~") exit(0) elif command == 'help': help() else: query(command) ```

3.3 初始化函数的功能

```python * 创建数据存储目录 * 创建系统数据库文件 * 创建系统用户 * 赋予系统用户权限

def Initialization(): if not os.path.exists(db_path): os.mkdir(db_path) if not os.path.exists("data/table_information.xlsx"): Workbook().save("data/table_information.xlsx") if os.path.exists("data/system.xlsx"): print "Initializating......" else: creat_db('system') db = load_workbook("data/system.xlsx") permission_tb_col = ['database char[50] pk unique','select char','insert char','delete char','update char'] creat_table('permission', db, 'system',permission_tb_col) ```

目录结构

3.4 用户验证及登录模块

登陆处理

通过raw_input()函数获取用户输入的用户名和密码,交给check_login()函数来验证是否正确。如果check通过,输出欢迎界面并将全局变量user赋值。

python def login(): global user print "Please Login:" username = raw_input("username: ") password = raw_input("password: ") if check_login(username,password): print "Login Success!Welcome {}! 😊".format(username) user = username else: print "user not exist or password is wrong!😣 Try again." login()

check_login函数通过输入的username查询数据库中对应的密码,将查询结果和用户输入的值的md5加密值进行比较,如果一致,认为成功登陆。 如果密码不正确或无此用户,都输出error并要求用户再一次输入

python def check_login(username,password): db = load_workbook("data/system.xlsx") #right_pswd = select(password,user,{'username':username}) table = db['user'] col_list = list(iter_cols(table)) try: pos = col_list[0].index(username) except: return False right_pswd = col_list[1][pos] if hashlib.md5(password).hexdigest() == right_pswd: return True else: return False

登陆效果

3.5 创建表模块

语句

sql create table tbname (id int PK null,user char[10] )

在创建时将约束写入table_information表中。

python def creat_table(table_name,current_database,current_dbname,columns_list): # create table if table_name not in current_database.sheetnames: table = current_database.create_sheet(table_name) else: print (u"数据表已存在,请重新输入.") return if current_database.worksheets[0].title == 'Sheet': del current_database['Sheet'] #表创建完成,开始创建列 length = len(columns_list) #print length tbinfo = load_workbook("data/table_information.xlsx") tbinfo_tb = tbinfo[current_dbname] tbinfo_rows = tbinfo_tb.max_row column_names = [] for i in range(length): #将字段的属性写到table_information库中 column = columns_list[i].split(' ') tbinfo_tb.cell(row=tbinfo_rows+1+i,column=1).value = table_name tbinfo_tb.cell(row=tbinfo_rows+1+i, column=2).value = column[0] tbinfo_tb.cell(row=tbinfo_rows+1+i, column=3).value = column[1] for key in column[2:]: if key == 'null': tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=4).value = '1' elif key == 'not_null': tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=4).value = '0' elif key == 'unique': tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=5).value = '1' elif key == 'pk': tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=6).value = '1' elif key == 'fk': tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=7).value = '1' column_names.append(column[0]) for j in range(1, 8): if tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=j).value is None: tbinfo_tb.cell(row=tbinfo_rows + 1 + i, column=j).value = 'NULL' tbinfo.save("data/table_information.xlsx") for i in range(length): table.cell(row=1,column=i+1).value = column_names[i] #表第一行是列名 current_dbname = db_path + current_dbname + '.xlsx' current_database.save(current_dbname) print (u"数据表创建完成。")

table_information表(测试数据)

3.6 创建视图模块

语句

sql creat view view_name as select xx from xx

解析查询语句,将结果存在view库中,每一个视图已视图名作为表名写入view库中,在view库中设置一个sql表原来存储视图和对应的sql语句。

python def view(viewname,sql): """ file = view_path + viewname view = query(sql,'view') f = open(file, "w") f.write(str(view)) f.close() print "Success" """ db = load_workbook("data/view.xlsx") if viewname not in db.sheetnames: table = db.create_sheet(viewname) else: print ("view is exist.") return if db.worksheets[0].title == 'Sheet': del db['Sheet'] sql_table = db['sql'] maxrow = sql_table.max_row #在sql表中存view名和对应的sql语句 sql_table.cell(row=maxrow + 1, column = 1).value = viewname sql_table.cell(row=maxrow + 1, column = 2).value = sql table = db[viewname] views = query(sql, 'view') for i in range(len(views)): for j in range(len(views[i])): table.cell(row=i+1, column=j+1).value = views[i][j] db.save("data/view.xlsx")

3.7 插入模块

支持单组和多组的插入,单组的插入处理就是将sql语句中的要插入的数据处理成字典,再交给insert函数处理。

多组的话将每组字典加入数组再进行处理。在插入数据前通过check_Constraint函数进行约束检查,注释部分是用来处理嵌套语句的,逻辑是通过正则取出其中的子查询语句,带上tag参数交给query函数处理,将结果以数组形式返回。因为对表的操作也是先转化成数组,这样直接处理数组就ok。

```python def insert(table_name, current_database, current_dbname, columns_list): if not check_Constraint(columns_list,table_name): #columns应为[dict] print "Constraint Error" return False table = current_database[table_name] for columns in columns_list: table_rows = table.max_row table_columns = table.max_column length = len(columns) # print length for i in range(length): column = re.search('((.*?))', columns[i], re.S).group(1) column_list = column.split(',') chk_len = len(column_list) if chk_len != table_columns: print ('插入失败,请检查输入的数据数量是否与列数量对应。') return

        else:
            for j in range(chk_len):
                table.cell(row=table_rows + i + 1, column=j + 1).value = column_list[j]
            current_dbname = db_path + current_dbname + '.xlsx'
            current_database.save(current_dbname)
            print ("数据插入完成。")

def check_Constraint(columns,tablename): #columns={'a':'xx'} db = load_workbook("system/table_information.xlsx") table = db[using_dbname] rows = [] rows_list = list(iter_rows(table)) #所有行 cols_list = list(iter_cols(table)) for col in columns: value = columns[col] for i in range(len(cols_list[0])): #table对应的行 if cols_list[0][i] == tablename: rows.append(i) for line in rows: if rows_list[line][1] == col: typee, is_null, unique, pk, fk = rows_list[line][2:] if is_null == '0': if value == '': return False if unique == '1': if not check_unique(tablename,col,value): return False if pk == '1': if not check_unique(tablename,col,value) or value == '': return False if '[' in typee: typee, maxlen = re.findall('(\w )[(\d )]',type) #int[10] => int,10 else: maxlen = 1000 if len(value) > maxlen: return False if typee == 'int': if type(value) != type(1): return False if typee == 'char': if type(value) != type('c'): return False ```

3.8 更新数据

支持单组和多组的更新,单组的更新处理就是将sql语句中的要插入的数据处理成字典,再交给insert函数处理。

多组的话将每组字典加入数组再进行处理。在更新数据前通过check_Constraint函数进行约束检查,其他功能和insert的逻辑一样。

语句

sql UPDATE table_name SET column1=value1,column2=value2,... WHERE some_column=some_value;

python def update(table_name,current_database,current_dbname,columns_list,update_columns_list): if not check_Constraint(update_columns_list,table_name): #columns应为dict print "Constraint Error" return False table = current_database[table_name] table_rows = table.max_row # 行 table_columns = table.max_column # 列 length = len(columns_list) update_row_num = [x for x in range(2,table_rows+1)] columns_name = [] for cell in list(table.rows)[0]: columns_name.append(cell.value) for key in columns_list: flag = 0 for i in range(len(columns_name)): # 判断colmuns_list 是否有 not in colmus中的 if columns_name[i] == key: flag = 1 if flag == 0: # 输入的列名不存在 print("Unknown column '{}' in 'where clause'".format(key)) return for key in columns_list: column_num = columns_name.index(key) for i in update_row_num[::-1]: #倒着来 if table.cell(row=i, column=column_num+1).value != columns_list[key]: update_row_num.remove(i) if len(update_row_num) > 0: for i in update_row_num[::-1]: for j in range(1,table_columns+1): clu_name = table.cell(row=1, column=j).value table.cell(row=i, column=j).value = update_columns_list[clu_name] else: print("find 0 to update.") current_database.save(db_path + current_dbname + '.xlsx') print("更新完成,影响{}行".format(len(update_row_num)))

3.9 语句处理函数

```python * ql语句的处理与解析。 * 通过切词和正则来转化数据和调用各函数。 * 通过split将语句按照空格切成数组,先根据首词判断操作再细分。 * tag参数是为insert,view等函数需要用到查询结果但不输出是的标识,如果带着该参数调用select函数,不会打印结果而是将结果以数组返回。 * select操作的谓词通过predicate和symbol参数来标识,带着这两个参数调用select函数,具体参见select模块 * 如果都没匹配最后会输出错误

def query(sql,tag=''): sql_word = sql.split(" ") if len(sql_word) < 2: print "[!] Wrong query!" return operate = sql_word[0].lower() if operate == 'use': if sql_word[1] == 'database': try: use_db(sql_word[2]) except: print "[!]Error" else: print "[!]Syntax Error.\neg:>use database dbname" elif operate == 'create': if sql_word[1] == 'database': try: creat_db(sql_word[2]) except: print "[!]Create Error" elif sql_word[1] == 'table': columns_list = re.findall('((.*))', sql)[0].split(',') print columns_list, using_dbname try: creat_table(sql_word[2], using_db, using_dbname, columns_list) except: print "[!]Error" elif sql_word[1] == 'view': #creat view test1 as select * from user viewname = sql_word[2] sql = ' '.join(sql_word[4:]) view(viewname,sql)

    elif sql_word[1] == 'index':
        return
    else:
        print "[!]Syntax Error."
elif operate == 'select':
    pos = 0
    for i in range(len(sql_word)):
        if '(' in sql_word[i] and 'select' in sql_word[i]:
            pos = i
    if pos == 3:
        sql2 = sql_word[3][1:-1]
        query(sql2,tag='nesting')
        sql_word[3] = 'tmp'
        sql = ' '.join(sql_word)



    columns = sql_word[1]
    table_name = sql_word[3]
    if len(sql_word) > 4:
        #try:
        limit = sql_word[5].split()
        predicate = 'and'
        symbol = '='
        if ',' in sql_word[5]:
            limit = sql_word[5].split(',')
            predicate = 'and'
        elif '|' in sql_word[5]:
            limit = sql_word[5].split('|')
            predicate = 'or'
        elif '>' in sql_word[5]:
            #limit = sql_word[5].split()
            symbol = '>'
        elif '<' in sql_word[5]:
            #limit = sql_word[5].split()
            symbol = '<'
        elif len(sql_word) > 6:
            if sql_word[6] == 'in':
                limit = [sql_word[5] + '=' + sql_word[7]]
                predicate = 'in'
            if sql_word[6] == 'like':
                limit = [sql_word[5] + '=' + sql_word[7]]
                predicate = 'like'
        #except:
            #limit = [].append(sql_word[5])
        #print limit
        for i in range(len(limit)):
            limit[i] = limit[i].split(symbol)
        limit = dict(limit)
        return select(columns, table_name, limit, predicate=predicate, symbol=symbol, tag=tag)
    else:   #没where的情况
        return select(columns, table_name, tag=tag)
elif operate == 'grant':
    set_permission(sql_word[5], sql_word[3], sql_word[1])
elif operate == 'revoke':
    del_permission(sql_word[5], sql_word[3], sql_word[1])
elif operate == 'insert':   #INSERT INTO table_name col1=val1,col2=val2&col3=val3,col4=val4
    table_name = sql_word[2]
    columns_list = []
    if '&' in sql:
        cols = sql_word[3].split('&')   #[{xx},{xx}] 多组
        for p in range(len(cols)):
            col = cols[p]
            c = col.split(',')
            for i in range(len(c)):
                c[i] = c[i].split('=')
            cols[p] = dict(c)
        columns_list = cols
    else:
        cols = sql_word[3].split(',')
        for i in range(len(cols)):
            cols[i] = cols[i].split('=')
        columns_list.append(dict(cols))
    insert(table_name,using_db,using_dbname,columns_list)
elif operate == 'update':
    return
elif operate == 'help':
    if sql_word[1] == 'database':
        show_db()
    if sql_word[1] == 'table':
        usdbnm = using_dbname
        use_db('table_information')
        tbname = sql_word[2]
        select('*',usdbnm,{'table':tbname})
    if sql_word[1] == 'view':
        view_name = sql_word[2]
        use_db('view')
        select('sql','sql',{'viewnamw':view_name})
    if sql_word[1] == 'index':
        print "All Index:"
        indexs = os.listdir('data/index/')  # 第二种方法,从保存数据库信息的库中查询
        for index in indexs:
            if '.DS' not in index:
                print "[*] " + index[:-5]
else:
    print "[!]Syntax Error."

```

3.10 删除模块

会先check用户权限再进行操作。其他逻辑类似insert函数。

```python def delect(table_name,current_database,current_dbname,columns_list): #columns_list={'name1':'value1','name2':'value2'}

table = current_database[table_name]
table_rows = table.max_row  #行
table_columns = table.max_column    #列
length = len(columns_list)
delect_row_num = [x for x in range(2,table_rows+1)]
columns_name=[]
for cell in list(table.rows)[0]:
    columns_name.append(cell.value)
for key in columns_list:
    flag = 0
    for i in range(len(columns_name)):    #判断colmuns_list 是否有 not in colmus中的
        if columns_name[i] == key:
            flag = 1
    if flag == 0:   #输入的列名不存在
        print("Unknown column '{}' in 'where clause'".format(key))
        return
for key in columns_list:
    column_num = columns_name.index(key)
    for i in delect_row_num[::-1]:  #倒着来
        if table.cell(row=i, column=column_num+1).value != columns_list[key]:
            delect_row_num.remove(i)
if len(delect_row_num) > 0:
    for i in delect_row_num[::-1]:
        #print i,table_rows
        table.delete_rows(int(i))
else:
    print("find 0 to delect.")
current_database.save(db_path + current_dbname + '.xlsx')

print("删除完成,影响{}行".format(len(delect_row_num))) ```

3.11 权限检查模块

在用户对某对象进行操作之前确定该用户有没有操作权限。用户对对象的操作权限存储在system库中的permission表,在用户进行相关操作时先去查询该用户有没有该操作的权限。

python def check_permission(user,database,action): table = load_workbook("data/system.xlsx")['permission'] db_list = list(iter_cols(table))[0][1:] row = db_list.index(database)+2 action_list = list(iter_rows(table))[0] col = action_list.index(action)+1 allow_user = table.cell(row=row, column=col).value.split(',') if user in allow_user: return True else: print "Permission not allowed" return False

3.12 权限的赋予和回收模块

使用grant和revoke关键字赋予权限和回收权限,实质是对permision表中数据进行更新。

grant语句

sql grant select on test_tb for testuser

这里第一列是具有权限的对象,不只是数据库,可以是table,view,index,在函数对应函数处理时将数据库名变量换成其他对象就OK。

python def set_permission(user,database,action): db = load_workbook("data/system.xlsx") table = db['permission'] db_list = list(iter_cols(table))[0][1:] row = db_list.index(database) + 2 action_list = list(iter_rows(table))[0] col = action_list.index(action) + 1 allow_user = table.cell(row=row, column=col).value.split(',') if user in allow_user: print "user have this permission" else: table.cell(row=row, column=col).value = table.cell(row=row, column=col).value + ',' + user db.save("data/system.xlsx")

revoke语句

sql revoke select on test_tb for testuser

python def del_permission(user,database,action): db = load_workbook("data/system.xlsx") table = db['permission'] db_list = list(iter_cols(table))[0][1:] row = db_list.index(database) + 2 action_list = list(iter_rows(table))[0] col = action_list.index(action) + 1 allow_user = table.cell(row=row, column=col).value.split(',') if user in allow_user: if allow_user.index(user) == 0: table.cell(row=row, column=col).value = table.cell(row=row, column=col).value.replace(user, '') else: table.cell(row=row, column=col).value = table.cell(row=row, column=col).value.replace(',' + user, '') db.save("data/system.xlsx") else: print "user didn't have this permission"

3.13 约束检查模块

检查主码、外码、唯一性约束、非空约束等完整性约束。

单独的约束检查函数,在进行insert,update等操作时直接调用就OK。

```python def check_Constraint(columns,tablename): #columns={'a':'xx'} db = load_workbook("system/table_information.xlsx") table = db[using_dbname] rows = [] rows_list = list(iter_rows(table)) #所有行 cols_list = list(iter_cols(table)) for col in columns: value = columns[col] for i in range(len(cols_list[0])): #table对应的行 if cols_list[0][i] == tablename: rows.append(i) for line in rows: if rows_list[line][1] == col: typee, is_null, unique, pk, fk = rows_list[line][2:] if is_null == '0': if value == '': return False if unique == '1': if not check_unique(tablename,col,value): return False if pk == '1': if not check_unique(tablename,col,value) or value == '': return False if '[' in typee: typee, maxlen = re.findall('(\w )[(\d )]',type) #int[10] => int,10 else: maxlen = 1000 if len(value) > maxlen: return False if typee == 'int': if type(value) != type(1): return False if typee == 'char': if type(value) != type('c'): return False

def check_unique(tablename,column,value): table = using_db[tablename] col_pos = list(iter_rows(table))[0].index(column) #第几列 cols_list = list(iter_cols(table))[col_pos][1:] if cols_list.count(value) > 1: #该列中该值数量 return False else: return True ```

3.14 查询模块

```python * 支持嵌套查询,and,or,in,like谓词。 * 通过eval函数处理比较运算和数学运算 * 通过select等关键字个数判断子查询,子查询通过tag参数调用query函数获得查询结果数组 * query函数中语句的处理很关键,通过一些参数告诉select函数要返回什么样的值。提前讲语句处理成dict或list讲谓词等转换成符号方便select函数的处理。 * 查询时转换成数组方便操作

elif operate == 'select':
    pos = 0
    for i in range(len(sql_word)):
        if '(' in sql_word[i] and 'select' in sql_word[i]:
            pos = i
    if pos == 3:
        sql2 = sql_word[3][1:-1]
        query(sql2,tag='nesting')
        sql_word[3] = 'tmp'
        sql = ' '.join(sql_word)
    columns = sql_word[1]
    table_name = sql_word[3]
    if len(sql_word) > 4:
        #try:
        limit = sql_word[5].split()
        predicate = 'and'
        symbol = '='
        if ',' in sql_word[5]:
            limit = sql_word[5].split(',')
            predicate = 'and'
        elif '|' in sql_word[5]:
            limit = sql_word[5].split('|')
            predicate = 'or'
        elif '>' in sql_word[5]:
            #limit = sql_word[5].split()
            symbol = '>'
        elif '<' in sql_word[5]:
            #limit = sql_word[5].split()
            symbol = '<'
        elif len(sql_word) > 6:
            if sql_word[6] == 'in':
                limit = [sql_word[5] + '=' + sql_word[7]]
                predicate = 'in'
            if sql_word[6] == 'like':
                limit = [sql_word[5] + '=' + sql_word[7]]
                predicate = 'like'
        #except:
            #limit = [].append(sql_word[5])
        #print limit
        for i in range(len(limit)):
            limit[i] = limit[i].split(symbol)
        limit = dict(limit)
        return select(columns, table_name, limit, predicate=predicate, symbol=symbol, tag=tag)
    else:   #没where的情况
        return select(columns, table_name, tag=tag)

```

select函数,不仅仅提供查询的功能,还用来处理view的一部分数据,通过tag参数来标识数据如何处理。

查询函数

```python def select(columns,table_name,limit={},predicate='and', symbol='=', tag=''): #{'c':'x','d':'x'} if using_dbname == '': print "please choose databse!" return table = using_db[table_name] #print columns if columns == '*' and len(limit) == 0: columns_name = list(iter_rows(table))[0] table_print = PrettyTable(columns_name) for i in range(1,len(list(iter_rows(table)))): table_print.add_row(list(iter_rows(table))[i]) table_print.reversesort = True if tag == 'view': print table_print return list(iter_rows(table)) #view

    else:
        print(table_print)
else:
    sel_cols = columns.split(',')   #*的情况
    rows_list = list(iter_rows(table))  #所有的行
    cols = rows_list[0]
    col_pos = []
    limit_pos = []
    print_row = []
    limit_cols = list(limit)
    symbol = '==' if symbol == '=' else symbol
    if columns[0] != '*':
        for i in range(len(sel_cols)):
            col_pos.append(cols.index(sel_cols[i])) #要查的列的列号
    else:
        sel_cols = list(iter_rows(table))[0]
        col_pos = range(len(cols))
    for i in range(len(limit)):
        limit_pos.append(cols.index(limit_cols[i])) #where的列
    for i in range(1, len(rows_list)):
        match = 0
        if predicate == 'in':
            match_list = limit[limit_cols[0]]
            for j in len(match_list):
                if rows_list[i][limit_pos[0]] == match_list[j]:
                    print_row.append(i)
        if predicate == 'like':
            like_word = re.findall('(.*)\%',limit[limit_cols[0]])
            if like_word in rows_list[i][limit_pos[0]]:
                print_row.append(i)
        else:
            for j in range(len(limit_pos)): #通过eval实现比较运算
                if eval("'" + rows_list[i][limit_pos[j]] + "'" + symbol + "'" + limit[limit_cols[j]] + "'"):
                    match += 1
            if predicate == None:
                print_row.append(i)
            if predicate == 'and' and match == len(limit_pos):  #and时要全部匹配
                print_row.append(i)     #符合条件的行号
            if predicate == 'or' and match > 0: #or时至少一个匹配
                print_row.append(i)

    table_print = PrettyTable(sel_cols)
    for i in range(len(print_row)):
        add_rows = []
        for x in col_pos:
            add_rows.append(rows_list[print_row[i]][x])
        table_print.add_row(add_rows)
    table_print.reversesort = True
    if tag == 'view':
        return table_print
    elif tag == 'nesting':
        tmpdb = using_db
        table = tmpdb['tmp']
        for i in range(len(sel_cols)):
            table.cell(row=0,column=i+1).value = sel_cols[i]
        for i in range(len(print_row)):
            add_rows = []
            for x in col_pos:
                add_rows.append(rows_list[print_row[i]][x])
            for j in range(len(add_rows)):
                table.cell(row=i+2,column=j+1).value = add_rows[j]
        tmpdb.save("data/" + using_dbname + ".xlsx")

    else:
        #table_print.reversesort = True
        print(table_print)

```

3.15 索引模块

B+树的索引,将数据先处理成数组,每一组数据包含数据值和数据在表中的位置(起到指针的作用)。B+树的处理单独写了一个类,方便调用处理。

```python def index(current_database,table_name,column_name): table = current_database[table_name] table_columns = table.max_column table_rows = table.max_row column_num = 0 column_value = [] column_position = [] for i in range(1,table_columns+1): if table.cell(row=1,column=i).value == column_name: column_num = i if column_num == 0: print "no this column" return else: for i in range(2,table_rows+1): column_value.append(str(table.cell(row=i,column=column_num).value)) column_position.append('<{},{}>'.format(i,column_num)) column_value.sort() for i in range(len(column_value)): tmp = [column_value[i],column_position[i]] #like [1,aaa|<2,1>] column_value[i] = tuple(tmp) #like [(1,aaa|<2,1>)] #print column_value[0] bt = test_BPTree(column_value) indexname = table_name + '|' +column_name save_index(str(bt), indexname)

def save_index(bt,indexname): line = re.findall(r'[.*?]', bt) for i in range(len(line)): line[i] = line[i][2:-2].replace('|', '') file = open('data/index/' + indexname,'w') for i in range(len(line)): file.writelines(line[i] + '\n') file.close() ```

索引的存储,存储生成的b+树,每一行是B+树的一层。存储数据类型是字典。

```python def select_index(a) Pos = BPTree_search(a)

def update_index(table_name, column_name) index(using_db, table_name, column_name) ```

B+树的部分代码

```python class BPTree(object): … def search(self, node, key): i = bisect.bisect_left(node.keys, key) if i < len(node.keys) and key == node.keys[i]: if node.is_leaf(): return (node, i) else: return self.search(node.children[i + 1], key) if node.is_leaf(): return (None, None) else: # self.disk_read(node.children[i]) return self.search(node.children[i], key)

… def insert(self, key, value): if len(self.root.keys) == self._maxkeys: oldroot = self.root self.root = BPNode() self.root.children.append(oldroot) self.split_child(self.root, 0, oldroot) self.insert_nonfull(self.root, key, value) else: self.insert_nonfull(self.root, key, value) … def levels(self): leveldict = {}

    for level, node in self.bft(self.root):
        leveldict.setdefault(level, []).append(node)

    return leveldict

def pprint(self, width=80):
    leveldict = self.levels()
    keys = leveldict.keys()
    for k in keys:
        print ' '.join(str(e) for e in leveldict[k]).center(width)
    return leveldict

def min(self):
    node = self.root
    while node.children:
        node = node.children[0]
    return node.keys[0]

def max(self):
    node = self.root
    while node.children:
        node = node.children[-1]
    return node.keys[-1]

def bft(self, node, level=1):
    """Breadth first traversal."""
    q = Queue.Queue()
    level = level
    q.put((level, node))

    while not q.empty():
        level, node = q.get()
        yield (level, node)
        for e in node.children:
            q.put((level + 1, e))

… def ceiling(self, node, key): i = bisect.bisect(node.keys, key) if i < len(node.keys) and key == node.keys[i]: if node.is_leaf(): return key else: return self.ceiling(node.children[i + 1], key) if node.is_leaf(): if i == len(node.keys): kp = node.keys[-1] if node.keys[-1] < key: if len(node.next.keys) > 0: return node.next.keys[0

参考文献

  • 中小型企业仓库管理系统的设计与实现(吉林大学·郭楠)
  • 基于Web的卫星信息数据库系统的研究与实现(北京邮电大学·郑俐)
  • 基于.NET框架的Web数据库访问技术的研究与实现(武汉理工大学·希凡)
  • 基于网络爬虫的基金信息抽取与分析平台(华南理工大学·陈亮华)
  • 中小型企业仓库管理系统的设计与实现(吉林大学·郭楠)
  • 基于行列转换的统计功能研究与应用(中国海洋大学·张娜)
  • 库存管理系统的设计与实现(厦门大学·铁鑫磊)
  • 基于计算与存储分离的Key-Value数据库的研究与实现(电子科技大学·何毅帆)
  • 分布式统计信息基础数据库统计报表查询子系统的设计与实现(福州大学·曾瑾)
  • 基于触发器的数据库监控系统的设计与实现(南京大学·邓明)
  • 动态WEB数据库应用研究(昆明理工大学·李玉梅)
  • 基于行列转换的统计功能研究与应用(中国海洋大学·张娜)
  • 数据库虚拟实验室的研究与实现(中南大学·杨瑛瑛)
  • Web数据库系统的研究和实践(广东工业大学·何晓桃)
  • 基于J2EE和多维数据模型的金融数据分析系统(西安电子科技大学·王凯)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码工坊 ,原文地址:https://m.bishedaima.com/yuanma/35442.html

相关推荐

发表回复

登录后才能评论