Python 在没有主键的数据库中存储表是否不好?

Python 在没有主键的数据库中存储表是否不好?,python,sqlite,Python,Sqlite,我目前正在使用python开发一个列表实现,该实现将持久列表存储为数据库: 我正在解决一个设计问题,似乎SQLite允许我在没有主键的情况下存储数据 self.c.execute('SELECT * FROM unnamed LIMIT 1 OFFSET {}'.format(key)) 这行代码可以通过绝对行引用进行检索 这是坏习惯吗?我会在任何时候取消数据顺序吗?也许sqlite可以,但我的设计不会转换到其他数据库引擎?熟悉数据库的人的任何想法都会有所帮助。我写这篇文章是为了不必处理数据

我目前正在使用python开发一个列表实现,该实现将持久列表存储为数据库:

我正在解决一个设计问题,似乎SQLite允许我在没有主键的情况下存储数据

self.c.execute('SELECT * FROM unnamed LIMIT 1 OFFSET {}'.format(key))
这行代码可以通过绝对行引用进行检索

这是坏习惯吗?我会在任何时候取消数据顺序吗?也许sqlite可以,但我的设计不会转换到其他数据库引擎?熟悉数据库的人的任何想法都会有所帮助。我写这篇文章是为了不必处理数据库

报告说:

如果返回多行的SELECT语句没有ORDER BY子句,则返回行的顺序未定义

因此,不能简单地使用偏移量来标识行

主键约束只是告诉数据库,它必须对PK列强制唯一和非空约束。如果不声明主键,则不会自动强制执行这些约束,但这不会改变这样一个事实,即当您要访问行时,必须以某种方式标识行


存储列表项的最简单方法是将列表中的位置作为一个单独的列。如果您的程序在插入或删除列表条目时占用了大部分时间,那么最好不要将列表存储为数组,而是将其存储为链表,即数据库不存储位置,而是存储指向下一个条目的指针。

SQLite在内部为您生成一个主键,称为ROWID。在RDB理论中,在表中没有排序的概念,因此限制1偏移量{}将给出依赖于实现的结果;改用参数化查询。想象一下键3;删除未命名的表';使用self.c.execute'select*from unnamed limit 1 offset%s',key或您的库指定的任何格式。谢谢,我刚刚通过使用sqlitebrowser gui找到了这个ROWID,我想我当时正在做一个设计决定,我想让MySQLList也很好,现在想想,我会尝试编写一个安全的代码,在这里我有自己的id列并使用它,但也会根据sqlite的实现方式编写一个快速的代码。谢谢你,所以当我发现rowid时,我进行了一些重构并删除了我的自动增量id。我仍然不确定我是否可以依赖rowid,它似乎不是主键,但保留列表的顺序?所以我知道我不应该使用偏移量,但我可以按rowid订购,这样可以吗?如果这仍然是错误的,我想我回到一个主键id。。。但我有点喜欢单列表,好像它满足了用户的期望。感谢链表的想法,但是我觉得我现在会坚持使用非常次优的插入我的意思是,对于链表的事情,删除现在是可以的,没有问题,添加到表的末尾也是可以的。。。就我的使用而言,它非常棒,我想我可以将其记录下来。。。。。很抱歉问这个问题,如果可以的话,我能保证rowid的订单吗?主键会因为任何原因更快吗?谢谢如果您想使用rowid,您应该创建一个实际列。关于它的行为,请参阅。感谢您将我链接到该文档,我现在明白了。我发现sqlite文档非常广泛。对不起。好的,别名就是我的答案,我之前的设计是偶然的,它不浪费任何额外的资源,并通过索引搜索等尽可能快地运行。正确的设计就是我以前的主键列