【问题标题】:Load only the new rows in the database仅加载数据库中的新行
【发布时间】:2014-09-13 10:14:45
【问题描述】:

我有一个问题,如何只加载数据库中的新行并将它们显示到页面上,我应该使用 时间戳 来做到这一点吗? FacebookTwitter 如何只加载新的推文或帖子?我猜他们为此使用 timestamp,比如最后一次 ajax 调用什么时候。我知道 SQL 查询,我认为它看起来像这样。

SQLSELECT * FROM posts WHERE posted_date >= :timestamp,其中 timestamp 是当前时间戳,或者是请求的时间戳。

但是每当我输入任何数字,甚至超过posted_date,它总是返回true,它返回行,我不希望这样。

这是我的 PHP 代码:

    $pdo = new PDO('mysql:host=localhost;dbname=test;', 'root', '');
    $sql = "SELECT * FROM `posts` WHERE `posted_date` >= :curr_time";
    $stmt = $pdo->prepare($sql);
    $stmt->bindParam(':curr_time', $timestamp);
    $stmt->execute();

    if ($stmt->rowCount() > 0) {
        // If there was a result found
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode(array(
            'post_content' => $rows[0]['post_content'],
            'timestamp'    => strtotime($rows[0]['posted_date'])
            )); 
    } else {
        // If there was no results
        echo json_encode(array('message' => 'No results!'));
    }

希望你能理解我。

谢谢:)

【问题讨论】:

  • 您遇到的整个“问题”都围绕着定义“新”行是什么。由于必须告诉我们你认为什么是行,这个问题是不完整的,因为不清楚你在追求什么。我们不能为你施展黑魔法。
  • 新的,我猜你的意思是最近的?您需要在每条记录上存储时间戳/日期时间,然后按此排序
  • 新行是 post_content,我只是为了测试和其他东西这样做,所以这样想,用户像 Facebook 的帖子一样向数据库发布一些内容,我只想返回那个新帖子从数据库中,不是所有的......
  • 确保为每条记录使用自动递增主键 (id),然后在 INSERT 之后使用 LAST_INSERT_ID() 获取它
  • 基本上我想做的是,使用长轮询之类的东西,所以当 user1 发布内容时,它也会在 user2 的页面中更新,就像 Facebook 一样,我不需要现在的 AJAX 和 jQuery,只是 PHP 部分,我想使用 SELECT * FROM posts WHERE posted_date >= :curr_time 是正确的方法。如我错了请纠正我。谢谢。

标签: php mysql sql timestamp


【解决方案1】:

你可以只存储上次加载元素的ID,你也可以将它保存在会话中,下次你收到请求时,你会得到:

SELECT * FROM posts WHERE posted_id > :last_loaded_post_id

您也可以通过posted_date 进行限制以始终要求发布日期大于或等于CURDATE(),但这可能不是最佳选择,因为当它明天下午 23:59 之后到来时,您可能会输一些帖子。因此,存储并依赖于最后加载的项目 ID 是我认为的最佳解决方案。

SELECT * FROM posts 
WHERE posted_id > :last_loaded_post_id 
    AND posted_date >= CURDATE() /* to ensure posts from today */

您也可以通过 Javascript 管理它,具体取决于上一篇文章并获取它的 post_id 属性,并使用 ajax 请求传递它,但为了更安全,最好从服务器端管理

你的代码也有问题:它总是会返回 1 个结果,即使有更多

// If there was a result found
// this will always return first row, even if there are some more rows
 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
 echo json_encode(array(
     'post_content' => $rows[0]['post_content'],
     'timestamp'    => strtotime($rows[0]['posted_date'])
     )); 

【讨论】:

    【解决方案2】:

    好的,我解决了。这就是我所做的......

    首先:我创建了一个文件,用于存储服务器的当前timestamp,并以 JSON 格式回显。

    这是 getServerTime.php 文件。

    // Get the current server time as a UNIX timestamp.
    echo json_encode(array(
        'server_time' => time()
    ));
    

    当页面完全加载时,我对该文件进行 AJAX 调用并存储响应。在这种情况下,server_time 作为一个变量,所以我以后可以使用它...

    // When the page fully loads, We need to get the timestamp
    // Create a function that returns server time
    function get_server_time () {
        $.ajax({
            url: 'ajax/getServerTime.php',
            type: 'GET',
            dataType: 'JSON',
            success: function (data) {
                return server_time = data.server_time;
            }
        });
    }
    // We need to call it now, Why? Because the page is loaded.
    get_server_time();
    

    现在我需要创建一个 Javascript 函数,它将 AJAX 到 getNewPosts.php 并从那里返回行,所以这里是函数:

    $('#get_new_posts').click(function (event) {
        // We need to pass the server timestamp as a variable
        // Because we use it when we query our database
        function get_new_posts(timestamp) {
            $.ajax({
                url:'ajax/getNewPosts.php',
                type: 'GET',
                data: 'timestamp=' + timestamp,
                dataType: 'JSON',
                success: function(data) {
                    get_server_time();
                }
            });
        }
        // Remember when we set the `server_time` variable to the current server time?
        // We need it now, To call our function
        get_new_posts(server_time);
    });
    

    现在这里是 getNewPosts.php 里面的内容,我猜它是自我解释的。

    <?php
        // Set the header to JSON
        header('Content-type: application/json');
    
    
        // Get the timestamp from the url, Because we pass it through the AJAX call
        // If there is one, Then we set it to the GET variable
        // Other wise, We set it to null.
        $timestamp = isset($_GET['timestamp']) ? $_GET['timestamp'] : null;
        // I have to format the date to get it working
        $date = date('Y-m-d H:i:s', $timestamp);
    
        // Database query
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'akar', 'raparen');
    
        // Select the posts that are newer than the last ajax call
        $sql = 'SELECT * FROM `posts` WHERE `posted_date` >= :timestamp';
        $stmt = $pdo->prepare($sql);
        $stmt->bindParam(':timestamp', $date);
        $stmt->execute();
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    
        // If there was any results, Display them
        if ($stmt->rowCount() > 0) {
            echo json_encode($rows);
        } else {
    
    
         // Otherwise, No new posts.
         echo json_encode(array(
             'message' => 'There are no new posts...'
            ));
        }
    

    这解决了我的问题,我希望你们至少知道我在说什么。

    谢谢!

    【讨论】:

    • 你可能错了,因为它可能适用于一个用户,但不适用于多个用户,一些冲突将不可避免地发生
    • 我只是为了测试而做的,如果有多个用户,我会做一些其他的事情。
    • 没有必要手动存储时间来归档,当您可以轻松地使用会话时:)))
    • 这不仅是错误的答案,而且要复杂得多,只需在表上有一个索引,无论如何您都必须有一个索引,并获取具有 Id 的记录>您在客户端拥有的更大 id .另外,这不起作用,因为如果您在页面加载时有新记录,您将永远看不到它们。
    【解决方案3】:

    而不是使用:

    WHERE `post_date` >= :curr_time
    

    您可以在 DESCENDING 模式下使用字段 post_date 简单地对结果进行排序。如果您这样做,那么最新的帖子将首先显示。您的查询看起来像

    SELECT * FROM `posts` ORDER BY `post_date` DESC
    

    如果您尝试这种方法,请不要忘记限制您的结果。您仍然可以使用 WHERE 字段来满足您的需求。如果您想将帖子限制为 10 个最新帖子,则只需运行

    SELECT * FROM `posts` ORDER BY `post_date` LIMIT 0,10
    

    这将返回从最新帖子开始的 10 行。

    P.S.:我假设“新”帖子是指“最新”帖子,按添加到数据库的日期排序。

    【讨论】:

    • 我想这会很慢,我相信默认情况下,MySQL 索引是按升序存储的(如果你在 post_date 上有索引的话)。
    【解决方案4】:

    因此,根据您的 cmets,您希望最终实现轮询以获取(由用户 A)创建的最后一条记录并将其显示给用户 B

    因此,假设您的插入语句正常工作,获取最后创建的记录很简单:

    SELECT * FROM mytable ORDER BY id DESC LIMIT 1
    

    这假设您有一个名为 id 的自动递增主键,如果没有(您可能应该有!),您可以使用创建日期,例如:

    SELECT * FROM mytable ORDER BY created DESC LIMIT 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 2021-05-06
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多