我的mySQL数据库中哪些列应该被索引?

我的mySQL数据库中哪些列应该被索引?,mysql,database,database-design,Mysql,Database,Database Design,我正试图为我正在开发的程序设计我的数据库。我希望在我发布我的程序之前,它的设计是完美的,因为我听说一旦它运行起来就很难改变。总之,我的程序是一个买卖书籍的平台。用户可以在一个“距离”内搜索,以查看在指定的搜索距离内是否有该特定isbn的书籍。他们可以按价格或日期列出这些书。我将在下表中描述我的程序需要采取的行动: BookListings (table)... userID VARCHAR(50) NOT NULL dateListed timestamp Default: C

我正试图为我正在开发的程序设计我的数据库。我希望在我发布我的程序之前,它的设计是完美的,因为我听说一旦它运行起来就很难改变。总之,我的程序是一个买卖书籍的平台。用户可以在一个“距离”内搜索,以查看在指定的搜索距离内是否有该特定isbn的书籍。他们可以按价格或日期列出这些书。我将在下表中描述我的程序需要采取的行动:

BookListings (table)...

    userID VARCHAR(50) NOT NULL
    dateListed timestamp Default: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    isbn13 VARCHAR(20) NOT NULL
    price UNSIGNED TINYINT NOT NULL
    email VARCHAR(30) NOT NULL
    phone VARCHAR(20) NOT NULL
    condition VARCHAR(30) NOT NULL
    latitude FLOAT(9,7) NOT NULL
    longitude FLOAT(9,7) NOT NULL

ContactInfo (table)...

   email VARCHAR(30) NOT NULL
   phone VARCHAR(20) NOT NULL
请记住,ContactInfo表并不是很重要。每当我将信息移出数据库以释放空间时,我会经常清除它。如果这个表导致了严重的效率问题,我可以完全牺牲它,我就不会真的感到烦恼了

横幅(表格)

  • userIDVARCHAR(50)不为空
  • banReasonVARCHAR(50)不为空
BannedUsers表是我将跟踪禁令的地方。它将很少被使用,但如果出于某种原因我想禁止某人使用我的程序,我可以把他们的用户ID放在那里。当我的程序启动时,它会检查BannedUsers表,看看用户是否被禁止,如果是,它会告诉他们禁止的原因

我有点困惑在哪里放置索引(我对它们不太了解)。我只是听说索引大大加快了搜索速度。对于我的横幅,我认为在userID列上放置索引是显而易见的?如果是,什么样的指数

对于BookListings表来说,在哪里放置索引更让我困惑。首先,我将解释我的程序的所有功能(要执行的操作)以及从php脚本中执行的查询:

  • 我使用以下查询将列表输入到我的系统中。这是为了当用户想要出售一本书时,他们会“列出”这本书。所以你可以想象这个动作会做很多
  • 当用户想要购买(搜索)距离他们一定距离内的图书列表时,我使用以下查询。与列出书籍的查询一样,此操作也会被大量使用:
  • 在程序开始时使用以下查询来确定系统中列出了多少本书(只是为了有趣地计算系统处理了多少本书,其实并不重要):
  • 以下查询用于查找用户在系统中列出的所有书籍。这将是相当频繁的,因为他们需要这样做之前,他们删除一个清单,他们作出。它基本上用于向他们显示所有列表,然后他们选择要删除的列表:
  • 以下是他们实际删除列表的查询:

  • 请帮助我使我的设计更有效率。我不太确定在哪里索引,因为我知道索引意味着更新和删除更加困难。。我的程序也需要这样做。起初我想索引isbn13(将被搜索的主要内容),但后来意识到我也将搜索纬度和经度,所以我不确定这些是否也必须被索引。。。这真让我困惑。请告诉我我能做些什么来改进数据库的设计和查询。

    没有免费的午餐。索引既有好处,也有代价

    好处是某些操作会更快

    其代价是某些操作会变慢,并且会消耗更多的磁盘空间和内存

    查找记录(包括查找更新和删除记录)会更快,但更新、删除和插入记录会更慢,因为索引需要更新


    您的查询当前是否缓慢?为什么?你需要看看你的执行计划,看看他们为什么慢。如果它们由于顺序扫描而变慢,请尝试添加索引。这对插入、删除和更新有何影响?它值这个价吗?您是否有足够的磁盘空间和内存用于这些索引?这些问题我们无法为您解答

    >两个索引->代码>清单(USEID)<代码> >和代码>清单(ISBN13)脱颖而出,但将需要一个地理空间专家来建议你在<代码>距离>代码>优化。考虑看这个问题和它的答案:如果你住,我不知道,Laos东部说什么?我不确定吗?你指的是什么?如果你的经度是一个3位数怎么办?我不知道在没有我的程序激活的情况下如何测试这些东西。我应该插入一堆“假”数据进行测试吗?现在他们什么都没有,因为我还没有真正的程序。我只是想采取一种积极主动的方法。我已经在我的数据库中添加了1000个“测试”条目以供使用。可能会增加到10000。有1000个条目,没有任何索引,查询仍然是即时的。我已经在10000个“测试”条目的测试样本上运行了一些测试查询。我特别注意到,当我查询删除一个列表时,添加索引时,查询时间实际上要快得多。我认为添加索引会降低插入和删除查询的速度?无索引查询平均时间=0.0382秒,索引仅为isbn13查询平均时间=0.00236秒。我是做错了什么还是这是合理的行为?@user4233467索引可以加快删除速度,因为数据库可以更快地找到记录,但它仍然必须更新索引才能删除记录。无论如何,是的,您应该加载真实的测试数据,并编写一些模拟用户操作的测试
    INSERT INTO Listings
    VALUES ('$userID', (NOW() + INTERVAL 2 HOUR), '$isbn13', $price, '$email', '$phone', 
            '$condition', '$latitude', '$longitude')
    
    SELECT
        *, (
          6371 * acos (
          cos ( radians($userLatitude) )
          * cos( radians( latitude ) )
          * cos( radians( longitude ) - radians($userLongitude) )
          + sin ( radians($userLatitude) )
          * sin( radians( latitude ) )
        )
    ) AS distance
    FROM Listings
    WHERE isbn13='$isbn13'
    HAVING distance <= $withinDistance
    ORDER BY price, dateListed
    
    SELECT
        *, (
          6371 * acos (
          cos ( radians($userLatitude) )
          * cos( radians( latitude ) )
          * cos( radians( longitude ) - radians($userLongitude) )
          + sin ( radians($userLatitude) )
          * sin( radians( latitude ) )
        )
    ) AS distance
    FROM Listings
    WHERE isbn13='$isbn13'
    HAVING distance <= $withinDistance
    ORDER BY dateListed DESC
    
    INSERT INTO ContactInfo
    VALUES ('$email', '$phone')
    
    SELECT COUNT(*) FROM ContactInfo
    
    SELECT dateListed, isbn13, price 
    FROM Listings 
    WHERE userID='$userID' 
    ORDER BY dateListed DESC
    
    DELETE FROM Listings WHERE userID='$userID' AND isbn13='$isbn13