奇数据库设计,需要指导

Sam*_*a P 13 php mysql database database-design

我可能正在考虑这个错误但是这里有.

计算机开始在一个线性行中吐出11111111111111111111和99999999999999999999之间的无数随机数:

  • 有时,计算机会在行的一端添加一个数字.
  • 有时,计算机会在行的另一端添加一个数字.
  • 每个号码都有一个之前或将来的号码.
  • 每个号码都有一个后来或将来的号码.
  • 并非所有数字都是唯一的,许多但不是大多数都是重复的.
  • 电脑永远不会停止吐出数字.

当我记录所有这些数字时,我需要能够在任何给定时间做出有根据的猜测:

  • 如果这是我第二次看到一个数字,我必须知道它上次排在前面的数字.

  • 如果它出现了两次以上,我必须知道它前面的数字的概率/频率.

  • 如果这是我第二次看到一个号码,我也必须知道上次排队后的号码.

  • 如果它出现了两次以上,我必须知道它之后的数字的概率/频率.


我如何构建MySQL数据库中的表来存储所有这些数字?我使用哪种引擎?为什么?我如何制定我的查询?我需要快速了解,但容量也很重要,因为什么时候会停止吐出它们?

我构思错误的计划:

2表:

1. Unique ID/#
2. #/ID/#
Run Code Online (Sandbox Code Playgroud)

我的想法:

唯一ID几乎总是比数字=更快的匹配更短.数字重复=更少ID行=最初匹配更快.

Select * in table2 where id=(select id in table1 where #=?)
Run Code Online (Sandbox Code Playgroud)

要么:

3表:

1. Unique ID/#
2. #/ID
3. ID/#
Run Code Online (Sandbox Code Playgroud)

我的想法:

如果我只需要左/前,或只需要后/右,我缩小第二个查询的大小.

SELECT # IN table2(or 3) WHERE id=(SELECT id IN table1 WHERE #=?)
Run Code Online (Sandbox Code Playgroud)

要么

1表:

1. #/#/#
Run Code Online (Sandbox Code Playgroud)

思考:

减少查询=减少时间.

SELECT * IN table WHERE col2=#.
Run Code Online (Sandbox Code Playgroud)

我迷路了.... :(每个数字都有四个属性,它们来自+频率之前和+频率之后.

以这种方式思考它会更好吗?如果我在表格中存储并增加频率,我会不再重复,从而加快查询速度?我最初认为如果我存储每一个事件,以编程方式计算频率会更快.......

这样简单的数据,但我只是不知道数据库如何知道哪个更有效.


根据最近的评论,我想补充一些关于实际问题的信息:我有一串不确定的长度.我试图在这个字符串中存储各种字符或字符块的马尔可夫链频率表.

给定字符串中的任何一点我需要知道下一个状态的概率,以及前一个状态的概率.

我期待用户输入,基于文本语料库和过去的用户输入.与我见过的其他应用程序相比,一个主要的区别是,我在给定时间进一步向下,更多状态,我需要频率数据来提供多种可能性.

我希望能更清楚地说明这些图片.我不想深入研究问题的细节,因为在过去我创造的问题不够具体,无法得到具体的答案.


这似乎好一点.我对这个解决方案的主要问题是:提供"密钥"(状态的前几个字符)是否会提高系统的速度?即查询state_key,然后只查询该查询的结果为完整状态?

Table 1:
name: state
col1:state_id - unique, auto incrementing
col2:state_key - the first X characters of the state
col3:state - fixed length string or state

Table 2:
name: occurence
col1:state_id_left - non unique key from table 1
col2:state_id_right - non unique key from table 1
col3:frequency - int, incremented every time the two states occur next to each other.

QUERY TO FIND PREVIOUS STATES:
SELECT * IN occurence WHERE state_id_right=(SELECT state_id IN state WHERE state_key=? AND state=?)

QUERY TO FIND NEXT STATES:
SELECT * IN occurence WHERE state_id_left=(SELECT state_id IN state WHERE state_key=? AND state=?)
Run Code Online (Sandbox Code Playgroud)

and*_*dez 2

我不熟悉马尔可夫链,但这里尝试回答这个问题。注意:为了简单起见,我们将每个数字串称为“状态”。

首先我想象一张这样的桌子

Table states:
order : integer autonumeric (add an index here)
state_id : integer (add an index here)
state : varchar (?)
Run Code Online (Sandbox Code Playgroud)

顺序:只需使用顺序号(1,2,3,...,n),这将使搜索上一个或下一个状态变得容易。

state_id:与状态关联的唯一编号。例如,您可以使用数字 1 来表示状态“1111111111...1”(无论序列的长度是多少)。重要的是,状态的再次出现需要使用之前使用过的相同的state_id。您也许可以根据字符串制定 state_id(也许减去一个数字)。当然,只有当可能的状态数量适合 MySQL int 字段时,state_id 才有意义。

状态:这是数​​字“11111111...1”到“99999999...9”的字符串...我猜这只能存储为字符串,但如果它适合整数/数字列,您应该尝试一下,因为很可能您不需要 state_id

state_id 的要点是搜索数字比搜索文本更快,但在性能方面总会有权衡……分析并识别瓶颈以做出更好的设计决策。

那么,如何查找先前出现的状态 S_i ?

“SELECT order, state_id, state FROM states WHERE state_id = ”,然后附加 get_state_id(S_i),其中 get_state_id 理想情况下使用公式来生成该州的唯一 id。

现在,使用 order - 1 或 order + 1,您可以访问发出附加查询的相邻状态。

接下来我们需要跟踪不同发生的频率。您可以在另一个表中执行此操作,如下所示:

Table state_frequencies:
state_id integer (indexed)
occurrences integer
Run Code Online (Sandbox Code Playgroud)

并且仅在获得数字后添加记录。

最后,您可以使用表格来跟踪相邻州的频率:

Table prev_state_frequencies (next_state_frequencies is the same):
state_id: integer (indexed)
prev_state_id: integer (indexed)
occurrences: integer
Run Code Online (Sandbox Code Playgroud)

您将能够通过查看状态的出现次数(在 state_frequencies 中)与其前任状态的出现次数(在 prev_state_frequencies 中)来推断概率(我猜这就是您想要做的)。

我不确定我是否正确地解决了您的问题,但如果这是有道理的,我想我已经解决了。

希望有帮助,啊啊

  • 对于什么是有价值的:20 位数字不适合无符号 BIGINT,但 19 位数字可以。如果这很重要,那么您需要使用 varchar(20) 字段进行搜索,并可能为其添加索引。 (2认同)