在MySQL数据库中存储和查询大量可变长度列表的最佳方法是什么?

时间:2015-05-20 04:31:49

标签: python mysql database sqlalchemy

通过一个例子,这个问题可能会更清楚。让我们说我正在使用的数据集是一大堆(几千兆字节)可变长度的元组列表,每个元组都与一个唯一的ID和一些元数据相关联,我希望能够快速完成按ID查找任何这些列表。

我目前有两个表设置或多或少像这样:

TABLE list(
  id VARCHAR PRIMARY KEY, 
  flavor VARCHAR, 
  type VARCHAR, 
  list_element_start INT, 
  list_element_end INT)

TABLE list_element(
  id INT PRIMARY KEY, 
  value1 FLOAT, 
  value2 FLOAT)

要从数据库中提取特定列表,我目前执行以下操作:

SELECT list_element_start, list_element_end FROM list WHERE id = 'my_list_id'

然后我使用检索到的list_element_startlist_element_end值来获取列表元素:

SELECT * 
  FROM list_element 
  WHERE id BETWEEN(my_list_element_start, my_list_element_end)

当然,这种方法非常快,但我觉得有更好的方法可以做到这一点。我知道我可以在list_element_end中有另一个名为list_id的列,然后执行SELECT * FROM list_element WHERE list_id = 'my_list_id' ORDER BY id之类的操作。但是,在我看来,拥有该额外列以及该列上的外键索引会占用大量不必要的空间。

有更简单的方法吗?

如果之前已经问过这个问题,请道歉,但我无法找到答案。如果可能的话,我也想在Python中使用SQLAlchemy来完成所有这些工作。

提前致谢!

2 个答案:

答案 0 :(得分:0)

您可以将数组的每个元素规范化为一行。以下是SQLAlchemy中的声明式样式,它将为您提供带有flavor等的“MyList”对象,然后元素将是每个“MyElement”对象的实际Python列表。你可能会在返回的元素列表中清除额外的id和idx变得更加复杂,但这应该足够快。

另外,上面你已经为你的主键混合了varchar和int,不确定它是否只是疏忽,但是你不应该这样做。此外,在处理大型数据集时,请记住分块等选项。您可以使用偏移和限制来处理较小的尺寸并迭代处理。

class MyList(Base):
    __tablename__ = 'my_list'
    id = Column(Integer, primary_key=True)
    flavor = Column(String)
    list_type = Column(String)
    elements = Relationship('my_element', order_by='my_element.idx')

class MyElement(Base):
    __tablename__ = 'my_element'
    id = Column(Integer, ForeignKey('my_list.id'))
    idx = Column(Integer)
    val = Column(Integer)
    __table_args__ = (PrimaryKeyConstraint('id','idx'), )

答案 1 :(得分:0)

之间不是一个功能,所以我不知道你认为在那里发生了什么。无论如何......为什么不呢:

SELECT e.* 
  FROM list_element e
  Join list l
   On l.id between e.my_list_element_start and my_list_element_end

或者我错过了什么