我有两个表,tracklisttrack,其中tracklist有许多tracks。在某些时候,我将接收到用户输入,这是一个跟踪列表,我需要创建那个跟踪列表,或者返回一个现有的跟踪列表(这是因为跟踪列表对用户来说是完全透明的)。
我天真的解决方案是找到所有带有n轨迹的轨迹列表,并根据tracktracklist次连接n,根据用户输入数据检查每个连接。例如,有两个音轨:

SELECT tracklist.id FROM tracklist
  JOIN track t1 ON tracklist.id = t1.tracklist
  JOIN track_name tn1 ON t1.name = tn1.id
  JOIN track t2 ON tracklist.id = t2.tracklist
  JOIN track_name tn2 ON t2.name = tn2.id
 WHERE tracklist.track_count = '20'
   AND (t1.position = 1 AND tn1.name = 'Pancakes' AND t1.artist_credit = '42' AND t1.recording = 1)
   AND (t2.position = 2 AND tn2.name = 'Waffles' AND t2.artist_credit = '9001' AND t2.recording = 2)

然而,这并不能很好地扩展到大型跟踪列表我最基本的计时显示,对于10个轨迹列表,这可能需要>500毫秒,对于100个轨迹列表,这可能需要~7秒。虽然后者是一种边缘情况,但无论我使用什么算法,至少都需要能够扩展到这个程度。
不过,我还得考虑其他的解决办法。我唯一能想到的另一件事是选择所有带有n轨迹的轨迹列表及其所有轨迹,然后在应用程序代码中进行比较。不过,如果可以的话,我真的很想把这个保存在数据库服务器上。
下面是我正在使用的架构:
CREATE TABLE track
(
    id                  SERIAL,
    recording           INTEGER NOT NULL, -- references recording.id
    tracklist           INTEGER NOT NULL, -- references tracklist.id
    position            INTEGER NOT NULL,
    name                INTEGER NOT NULL, -- references track_name.id
    artist_credit       INTEGER NOT NULL, -- references artist_credit.id
    length              INTEGER CHECK (length IS NULL OR length > 0),
    edits_pending       INTEGER NOT NULL DEFAULT 0,
    last_updated        TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE TABLE track_name (
    id                  SERIAL,
    name                VARCHAR NOT NULL
);

CREATE TABLE tracklist
(
    id                  SERIAL,
    track_count         INTEGER NOT NULL DEFAULT 0,
    last_updated        TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

有什么建议吗?

最佳答案

  SELECT DISTINCT tracklist
    FROM track t0
    WHERE
      (SELECT COUNT(DISTINCT tracklist)
        FROM track t1
          WHERE
            (
              (t1.id='test1.id')
              OR
              (t1.id='test2.id')

              ......
              OR
              (t1.id='testn.id')
            )
      = 1);

  -- This is OK if you have the track ids for this query.
  -- If you do not then you need to replace each of the t1.id='testm.id' statements
  -- with:
  --      t1.recording='testm.recording' AND
  --      t1.tracklist='testm.tracklist' AND
  --      t1.position='testm.position' AND
  --      t1.name='testm.name' AND
  --      t1.artist_credit='testm.artist_credit' AND
  --      t1.length='testm.length' AND
  --      t1.edits_pending='testm.edits_pending' AND
  --      t1.last_updated='testm.last_updated'

由于我可能没有完全正确的语法,也没有机会对其进行测试,下面将对我要实现的目标进行书面描述:
我建立了一个查询,返回您拥有的曲目列表构建完此查询后,我将检查这些轨迹的轨迹列表是否都相同如果是,即查询中只有一个轨迹列表,则这是您需要的轨迹列表。如果在查询中没有跟踪列表,或者不止一个,那么跟踪集就不对应于任何单个现有的跟踪列表,因此需要创建一个新的跟踪列表。如果有必要,此查询不处理实际的创建。我不确定它将如何处理退化的情况-查询中根本没有跟踪;或者没有列出任何跟踪的跟踪列表。

08-25 23:04