0%

Lab_dataSolve

华东师范大学软件工程学院实践报告

实验课程:数据库系统实践 姓名:刘佳奇 学号:10225101455
实验名称:Lab3 函数与存储过程 实验日期:2024/4/25 指导老师:姚俊杰

实验目的

通过对实际数据集操作体会python与sql的结合,以及熟悉数据库扩容等操作。

实验环境

  • Vscode

实验过程与分析

Q1. 对数据集进行扩充

import os

def get_realpath(relative_path):
    cwd = os.getcwd()
    return os.path.join(cwd, relative_path)

KAGGLE_INPUT_PATH   = get_realpath('datas/kaggle/input')
KAGGLE_WORKING_PATH = get_realpath('datas/kaggle/working')

def get_relativepath(realpath, basepath=KAGGLE_INPUT_PATH):
    cwd = os.getcwd()
    return os.path.relpath(realpath, basepath)

import numpy as np    # linear algebra
import pandas as pd   # data processing, CSV file I/O (e.g. pd.read_csv)

print('List files under KAGGLE_INPUT_PATH(', get_relativepath(KAGGLE_INPUT_PATH, os.getcwd()), '):\n')
import os
for dirname, _, filenames in os.walk(KAGGLE_INPUT_PATH):
    for filename in filenames:
        realpath = os.path.join(dirname, filename)
        relative_path = get_relativepath(realpath)
        print('   ', relative_path)
        
import sqlite3 as sql
from os import path

db_connection = path.join(KAGGLE_INPUT_PATH, "mubi-sqlite-database-for-movie-lovers/mubi_db.sqlite")
conn = sql.connect(r'E:\apps\Vscode\Python\Lab\datas\kaggle\input\mubi-sqlite-database-for-movie-lovers\mubi_db.sqlite')
# 读取最后10个数据
result1 = pd.read_sql_query("SELECT * FROM movies ORDER BY rowid DESC LIMIT 10", conn)
print(result1)

# 计算原始数据的行数
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM movies")
num_rows = cursor.fetchone()[0]
print("Total number of rows in 'movies' table:", num_rows)

# 使用整个数据集的一半行数进行抽样
selected_data = result1.sample(n=num_rows // 2, replace=True, random_state=42)

# 保存选择的数据到原来的数据集
selected_data.to_sql('movies', conn, if_exists='append', index=False)

# 读取新数据集的前几行进行检查
result2 = pd.read_sql_query("SELECT * FROM movies ORDER BY rowid DESC LIMIT 10", conn)
print(result2)

# 计算原始数据的行数
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM movies")
num_rows2 = cursor.fetchone()[0]
print("Total number of rows in 'movies' table:", num_rows2)

在Pandas中,sample()函数用于从DataFrame中随机抽取样本。random_state设置随机种子保证每次抽取结果一致。随后将随机抽取的样本保存到原来的数据库。 运行结果:
运行结果

Q2. 将扩容后的数据集减小1/4数据量

db_connection = path.join(KAGGLE_INPUT_PATH, "mubi-sqlite-database-for-movie-lovers/mubi_db.sqlite")
# 连接到数据库
conn = sql.connect(r'E:\apps\Vscode\Python\Lab\datas\kaggle\input\mubi-sqlite-database-for-movie-lovers\mubi_db.sqlite')

# 计算原始数据的行数
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM movies")
num_rows = cursor.fetchone()[0]
print("Total number of rows in 'movies' table:", num_rows)

# 选择要保留的数据量(原始数据量的四分之三)
num_rows_to_keep = num_rows * 3 // 4

# 从数据库中随机选择要保留的数据
selected_data = pd.read_sql_query(f"SELECT * FROM movies ORDER BY RANDOM() LIMIT {num_rows_to_keep}", conn)

# 将所选数据保存到一个新的数据库表中
selected_data.to_sql('temp_movies', conn, if_exists='replace', index=False)

# 删除原来的 'movies' 表格
conn.execute("DROP TABLE IF EXISTS movies")

# 将临时表格 'temp_movies' 重命名为 'movies'
conn.execute("ALTER TABLE temp_movies RENAME TO movies") 

# 读取新数据表的前几行进行检查
result = pd.read_sql_query("SELECT * FROM movies LIMIT 10", conn)
print(result)

# 计算调整后的数据的行数
cursor.execute("SELECT COUNT(*) FROM movies")
num_rows_adjusted = cursor.fetchone()[0]
print("Total number of rows in 'movies' table after adjustment:", num_rows_adjusted)

从数据库随机选择要保留的四分之三数据,然后通过临时表格的媒介将原表覆盖。 运行结果: 运行结果

Q3. 实现嵌套查询

查找15年之后发行的电影的评论且title长度大于8。

# 执行SQL查询
query = """
SELECT *
FROM movies
WHERE LENGTH(movie_title) > 8
AND movie_id IN (
    SELECT DISTINCT movie_id
    FROM movies
    WHERE movie_release_year > 2015.0
)
"""
result = pd.read_sql_query(query, conn)

# 打印结果
print(result)

运行结果: 运行结果

Q4. 同时使用group by语句和where语句进行查询

选取mocie_title大于8的影评,同时按照movie_release_year进行分组。

# 执行SQL查询
query = """
SELECT movie_title, movie_release_year
FROM movies
WHERE LENGTH(movie_title) < 8
GROUP BY movie_release_year;
"""
result = pd.read_sql_query(query, conn)

# 打印结果
print(result)

运行结果:
运行结果

Q5. 关系代数式

一、 1. 获取最后10个数据

[ {} ({last_10} (_{True}(movies))) ] 其中,() 表示排序操作,() 表示重命名操作,() 表示选择操作。

  1. 计算原始数据的行数

[ _{} (movies) ] 其中,() 表示聚合操作。

  1. 抽样一半行数的数据

在 SQL 中没有直接的关系代数运算符来表示抽样,但我们可以通过以下关系代数表示要实现的抽样目标: [ _{*} ({} (movies)) ] 其中,() 表示投影操作,({}) 表示根据随机条件选择行。

  1. 保存选择的数据到原来的数据集

[ movies sampled_data ] 其中,() 表示并操作。

  1. 读取新数据集的前几行进行检查

[ {} ({last_10} (_{True}(movies))) ]

  1. 计算新的数据行数

[ {} (movies) ] 二、 1. 计算原始数据的行数: [ n {} (movies) ]

  1. 选择要保留的数据量(原始数据量的四分之三): [ m n ]

  2. 从数据库中随机选择要保留的数据: [ temp_movies _{*} (_{} (movies)) m ]

  3. 删除原来的 'movies' 表: [ movies ]

  4. 将临时表 'temp_movies' 重命名为 'movies': [ movies temp_movies ]

  5. 读取新数据表的前几行进行检查: [ _{*} ({top_10} ({True}(movies))) ]

  6. 计算调整后的数据的行数: [ new_n _{} (movies) ]

三、

[ result { ({} (_{ > 2015}(movies)))}(movies) ]

四、

[ result {} ({, } (_{}(movies))) ]

实验结果总结

结果归纳

  1. 对实际巨大数据集的扩容、缩小、查询等操作有了深入的了解。
  2. 对实际查询的SQL语句与关系代数式的对应有了深入的理解。
“富哥vivo50看看实力”