通过一个例子,这个问题可能会更清楚。让我们说我正在使用的数据集是一大堆(几千兆字节)可变长度的元组列表,每个元组都与一个唯一的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_start
和list_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来完成所有这些工作。
提前致谢!
答案 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
或者我错过了什么