简体   繁体   English

是否可以在MySQL表的顶部插入新行?

[英]Is it possible to insert a new row at top of MySQL table?

All rows in MySQL tables are being inserted like this: MySQL表中的所有行都是这样插入的:

1 1
2 2
3 3

Is there any way how to insert new row at a top of table so that table looks like this? 有没有办法如何在表的顶部插入新行,以便表格看起来像这样?

3 3
2 2
1 1

Yes, yes, I know "order by" but let me explain the problem. 是的,是的,我知道“按顺序”,但让我解释一下这个问题。 I have a dating website and users can search profiles by sex, age, city, etc. There are more than 20 search criteria and it's not possible to create indexes for each possible combination. 我有一个约会网站,用户可以按性别,年龄,城市等搜索个人资料。有超过20个搜索条件,并且不可能为每个可能的组合创建索引。 So, if I use "order by", the search usually ends with "using temporary, using filesort" and this causes a very high server load. 因此,如果我使用“order by”,搜索通常以“using temporary,using filesort”结束,这会导致非常高的服务器负载。 If I remove "order by" oldest profiles are shown as first and users have to go to the last page to see the new profiles. 如果我删除“order by”,则最旧的配置文件显示为第一个,用户必须转到最后一页才能看到新的配置文件。 That's very bad because first pages of search results always look the same and users have a feeling that there are no new profiles. 这非常糟糕,因为搜索结果的第一页看起来总是一样,用户感觉没有新的个人资料。 That's why I asked this question. 这就是我问这个问题的原因。 If it's not possible to insert last row at top of table, can you suggest anything else? 如果无法在表格顶部插入最后一行,您能否提出其他建议?

The order in which the results are returned when there's no ORDER BY clause depends on the RDBM. 没有ORDER BY子句时返回结果的顺序取决于RDBM。 In the case of MySQL, or at least most engines, if you don't explicitly specify the order it will be ascending, from oldest to new entries. 对于MySQL或至少大多数引擎,如果您没有明确指定它将从最旧到新条目的升序。 Where the row is located "physically" doesn't matter. 行位于“物理上”无关紧要。 I'm not sure if all mysql engines work that way though. 我不确定所有的mysql引擎是否都能以这种方式工作。 Ie, in PostgreSQL the "default" order shows the most recently updated rows first. 即,在PostgreSQL中,“默认”顺序首先显示最近更新的行。 This might be the way some of the MySQL engines work too. 这可能是一些MySQL引擎的工作方式。

Anyway, the point is - if you want the results ordered - always specify sort order, don't just depend on something default that seems to work. 无论如何,关键是 - 如果你想要结果排序 - 总是指定排序顺序,不要只依赖于似乎有用的默认值。 In you case you want something trivial - you want the users in descending order, so just use: 在你的情况下,你想要一些微不足道的东西 - 你希望用户按降序排列,所以只需使用:

SELECT * FROM users ORDER BY id DESC

I think you just need to make sure that if you always need to show the latest data first, all of your indexes need to specify the date/time field first, and all of your queries order by that field first. 我认为您只需要确保如果您始终需要首先显示最新数据,则所有索引都需要先指定日期/时间字段,并且所有查询首先按该字段排序。

If ORDER BY is slowing everything down then you need to optimise your queries or your database structure, i would say. 如果ORDER BY减慢了一切,那么你需要优化你的查询或数据库结构。

I know that a lot of time has passed since the above question was asked. 我知道自从提出上述问题以来已经过了很多时间。 But I have something to add to the comments: 但我还有一些内容可以添加到评论中:

I'm using MySQL version: 5.7.18-0ubuntu0.16.04.1 我使用的是MySQL版本:5.7.18-0ubuntu0.16.04.1

When no ORDER BY clause is used with SELECT it is noticeable that records are displayed, regardless of the order in which they are added, in the table's Prime Key sequence. 如果没有与SELECT一起使用ORDER BY子句,则可以注意到,在表的Prime Key序列中,无论添加顺序如何,都会显示记录。

Maybe if you add the id 'by hand', and give it a negative value, but i (and probably nobody) would recommend you to do that: 也许如果你手动添加id'并给它一个负值,但我(可能没有人)会建议你这样做:

  1. Regular insert, eg 常规插入,例如

    insert into t values (...); 插入t值(...);

  2. Update with set, eg 用set更新,例如

    update t set id = -id where id = last_insert_id(); update t set id = -id where id = last_insert_id();

Normally you specify a auto_incrementing primary key. 通常,您指定auto_incrementing主键。

However, you can just specify the primary key like so: 但是,您可以像这样指定主键:

CREATE TABLE table1 (
  id signed integer primary key default 1, <<-- no auto_increment, but has a default value
  other fields .....

Now add a BEFORE INSERT trigger that changes the primary key. 现在添加一个更改主键的BEFORE INSERT触发器。

DELIMITER $$

CREATE TRIGGER ai_table1_each BEFORE INSERT ON table1 FOR EACH ROW
BEGIN
  DECLARE new_id INTEGER;
  SELECT COALESCE(MIN(id), 0) -1 INTO new_id FROM table1;
  SET NEW.id = new_id;
END $$

DELIMITER ; 

Now your id will start at -1 and run down from there. 现在你的id将从-1开始并从那里开始运行。
The insert trigger will make sure no concurrency problems occur. 插入触发器将确保不会发生并发问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM