我在一次面试中被要求为一本记录同义词的词典设计数据库。同义词部分是采访中后来的一个问题我有一张桌子

    Words
=============
id |  ...
=============
 1 |   .
 2 |   .
 . |   .
 . |   .

所以为了把单词和单词联系起来,我做了一张桌子
       Synonyms
======================
 wordA_id | wordB_id
======================
     .    |    .
     .    |    .
     .    |    .

例如,如果id等于16972的单词是同义词,则
     1    |    69
     69   |    72

可能是Synonyms中的一个条目。但也有可能
     1    |    69
     1    |    72

我意识到了配对顺序无关紧要,所以
     69   |   1
     1    |   72

话也一样。我们可能不需要任何订单的重复记录,所以
     69   |   1
     1    |   72
     69   |   1

属于
     69   |   1
     1    |   72
     1    |   69

我想知道如何配置数据库来确保这一切。我建议(在采访中)通过一个检查所有这些的存储过程插入synnoms,比如
CREATE PROCEDURE InsertSynonym
   @idA INT,
   @idB INT
AS
   -- make @idA the smaller if it isn't already
   IF @idA > @idB
   BEGIN
      @DECLARE @temp INT
      SET @temp = @idA
      @idA = @idB
      @idB = @temp
   END
   -- insert if not already there
   IF NOT EXISTS (SELECT * FROM Synonyms WHERE wordA_id=@idA)
   BEGIN
      INSERT INTO Synonyms (wordA_id,wordB_id) VALUES (@idA,@idB)
   END

我的t-sql语法中有错误吗?
假设插入同义词的唯一方法是通过这个过程,那么逻辑是否覆盖了所有的情况,并且它是否防止Synonyms表的大小爆炸?
有没有更好的方法来设计这个同义词模式呢?
顺便问一下,是否可以在T-SQL中进行异或交换?

最佳答案

我看到一个bug,但它不是语法上的,而是逻辑上的。
IF NOT EXISTS应该包含在it's where子句中wordA_IdwordB_Id
另外,从数据库的描述中还不清楚,但是words-in-words表应该有一个唯一的索引,以及synonyms表中两列的组合。
我不确定是否有更好的数据库设计,但还有另一种选择,就是在单词表中使用自引用。然而,这需要self-reference列可以为空,虽然它完全受所有主要数据库的支持,但它是frowned upon
要回答有关异或交换的问题-在t-sql中是可能的:

DECLARE @A int = 5, @B int = 7;

SELECT @A as A, @B as B

SELECT  @A = @A ^ @B,
        @B = @A ^ @B,
        @A = @A ^ @B

SELECT @A as A, @B as B

结果:
A           B
----------- -----------
5           7


A           B
----------- -----------
7           5

关于sql - 在SQL数据库中设计同义词库的最佳方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36301501/

10-14 14:58