代码之家  ›  专栏  ›  技术社区  ›  max

如何在Python中实现数据库样式表

  •  6
  • max  · 技术社区  · 14 年前

    我正在实现一个类似于典型数据库表的类:

    • 具有命名列和未命名行
    • 有一个主键,通过它我可以引用行
    • 支持按主键和列标题进行检索和分配
    • 可以要求为任何列添加唯一或非唯一索引,以便快速检索在该列中具有给定值的行(或一组行)
    • 行的删除速度很快,并被实现为“软删除”:该行在物理上保持不变,但被标记为删除,并且不会出现在任何后续的检索操作中
    • 增加一列很快
    • 很少添加行
    • 列很少被删除

    我决定直接实现这个类,而不是使用sqlite的包装器。

    使用什么样的数据结构比较好?


    举个例子,我正在考虑的一种方法是词典。它的键是表的主键列中的值;它的值是按以下方式之一实现的行:

    1. 作为列表。列编号映射到列标题中(使用列表表示一个方向,使用地图表示另一个方向)。在这里,检索操作首先将列标题转换为列编号,然后在列表中找到相应的元素。

    2. 作为字典。列标题是这本词典的关键。

    不确定两者的利弊。


    我想自己编写代码的原因是:

    • 我需要跟踪行删除。也就是说,在任何时候,我都希望能够报告哪些行被删除,以及出于什么“原因”(将“原因”传递给我的delete方法)。
    • 在索引过程中,我需要一些报告(例如,当正在构建一个非唯一索引时,我想检查某些条件并报告它们是否被违反)。
    3 回复  |  直到 7 年前
        1
  •  2
  •   unutbu    14 年前

    您可能需要考虑创建一个类,该类在hood下使用内存中的sqlite表:

    import sqlite3
    
    class MyTable(object):
        def __init__(self):
            self.conn=sqlite3.connect(':memory:')
            self.cursor=self.conn.cursor()
            sql='''\
                CREATE TABLE foo ...
            '''
            self.execute(sql)
        def execute(self,sql,args):
            self.cursor.execute(sql,args)
        def delete(self,id,reason):
            sql='UPDATE table SET softdelete = 1, reason = %s where tableid = %s'
            self.cursor.execute(sql,(reason,id,))
        def verify(self):
            # Check that certain conditions are true
            # Report (or raise exception?) if violated
        def build_index(self):
            self.verify()
            ... 
    

    软删除可以通过 softdelete 列(bool类型)。 类似地,您可以有一个列来存储删除原因。 取消删除只需要更新行并更改 软删除 价值。 选择尚未删除的行可以使用SQL条件实现 WHERE softdelete != 1 .

    你可以写一个 verify 方法来验证数据是否满足条件。你可以从你的 build_index 方法。

    另一种选择是使用numpy结构的屏蔽数组。

    很难说什么是最快的。或许唯一确定的方法是为每个人编写代码,并使用timeit对真实数据进行基准测试。

        2
  •  2
  •   Morlock Anthony Flores    14 年前

    我会考虑用元组或列表键来构建字典。如: my_dict(("col_2", "row_24")) 会得到这个元素。从这里开始,编写“get-col”和“get-row”方法,以及前面两个方法中的“get-row-slice”和“get-col-slice”来访问您的方法将非常容易(如果不是非常快的话)。

    使用这样一本字典有两个好处。1) 获取单个元素的速度将比两个建议的方法快;2)如果您希望在列中包含不同数量的元素(或缺少的元素),这将使它非常容易,并且内存效率也非常高。

    只是想一想:)我很想知道人们会建议什么样的套餐!

    干杯

        3
  •  0
  •   Roger Binns    14 年前

    你真的应该使用SQLite。

    由于第一个原因(跟踪删除原因),您可以通过在删除时将行“移动”到第二个表来轻松实现这一点。原因可以在该表的其他列或可以联接的其他表中跟踪。如果删除原因并不总是必需的,那么您甚至可以在源表上使用触发器来复制将要删除的行,和/或使用用户定义的函数来获取原因。

    索引的原因在一定程度上被约束等所覆盖,但在没有更多细节的情况下,我不能直接处理它。