Sqlite效率

时间:2016-05-26 13:38:55

标签: python sqlite pandas relational-database

我参加了python,sql和datascience课程,在那里我被教导从网上读取或下载数据文件/表,并通过逐行浏览文件并从列中提取数据将其存储在sqlite数据库中并将它们存储在相应的sqlite表中。我的项目使用MTA地铁使用数据做了这个,所以我有一个数据库,包括'站','线','用法','日期'等表。从我学到的,使用像这样的关系数据库要快得多比平台更有效。但是,我仍然发现从数据库中读取数据是一个非常缓慢的过程。我想也许这只是与数据的大小(22列火车线,450站,1年的使用)有关,但我发现当我只是将数据存储在一个平台中时,我可以读得更快很多。

我的问题是 - 我错过了什么?这是正常的吗?或者它可能与我的代码有关?有人可以举例说明关系数据库的实际用法吗?

我知道我的问题很模糊,但我真的只是想了解关系数据库与平面表,而不太关心我的具体项目。

我的意思是 Flat Table

我使用术语“平面表”来表示一个基本的简单电子表格式表格,其中包含一个“工作表”上的所有数据。这是您致电df.to_sql()

时获得的

我如何查询/使用数据库

# Selecting descriptive data for a given station
# C_As are sub sections of a station and SCPS are Turnstile units
cur.execute('''
    SELECT Stations.stn_name, C_A.ca_name, SCPS.scp_num, Lines.line_name
    FROM Lines JOIN Stations JOIN Stn_Lines JOIN C_A JOIN SCPS ON
    Lines.line_id= Stn_Lines.line_id AND
    Stations.stn_id = Stn_Lines.stn_id AND
    C_A.station_id = Stations.stn_id AND
    SCPS.ca_id = C_A.ca_id
    WHERE Stations.stn_name = (?)
    ''', (name,))
stn_name = name #1
data = cur.fetchall()

或获取使用数据:

cur.execute('''SELECT 
    Stations.stn_name, Dates.date, SCPS.scp_num,
    SUM(Usage.entries_reading), SUM(Usage.exits_reading)
    FROM Stations JOIN SCPS JOIN Dates JOIN Usage ON
    Stations.stn_id = Usage.stn_id AND
    SCPS.scp_id = Usage.scp_id AND
    Dates.date_id = Usage.date_id
    WHERE Stations.stn_name = (?)
    GROUP BY SCPS.scp_num, Dates.date
    ''', (self.name,))
data = pd.DataFrame(cur.fetchall(), columns = ['STATION', 'DATE', 'SCP', 'T_ENTRIES', 'T_EXITS'])

尝试解释数据库表结构

大多数表都非常简单:

CREATE TABLE IF NOT EXISTS Dates (
    date_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    date VARCHAR(45) UNIQUE
    );
CREATE TABLE IF NOT EXISTS Times (
    time_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    time VARCHAR(45) UNIQUE
    );
CREATE TABLE IF NOT EXISTS SCPS (
    scp_id INTEGER UNIQUE,
    scp_num VARCHAR(45),
    ca_id INTEGER,
    PRIMARY KEY (scp_id, ca_id)
    );
CREATE TABLE IF NOT EXISTS C_A (
    ca_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
    ca_name VARCHAR(45) UNIQUE,
    station_id INTEGER,
    unit VARCHAR(45)
    );
CREATE TABLE IF NOT EXISTS Stations (
    stn_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    stn_name TEXT UNIQUE
    );

然而,复杂的是Usage表,它将所有数据链接在一起:

CREATE TABLE IF NOT EXISTS Usage (
     date_id INTEGER,
     time_id INTEGER,
     stn_id INTEGER,
     ca_id INTEGER,
     scp_id INTEGER,
     entries_reading INTEGER,
     exits_reading
    )

1 个答案:

答案 0 :(得分:1)

就个人而言,我不会创建只有一个有意义字段的表。日期和时间的实施方式只会引起头痛和额外的工作。而是将日期/时间戳值直接放在它们对应的表上。

您可以考虑输入索引和工作站名称,因为它用于查找。

我可以建议生成查询计划并进行分析吗?

还要看一下https://www.sqlite.org/queryplanner.html