Mysql insertion order [duplicate] - mysql

This question already has answers here:
Return rows in the exact order they were inserted
(4 answers)
Closed 4 years ago.
I don't know whether it is already answered. I hadn't got any answers.In Mysql tables, the rows will be arranged in the order of primary key. For example
+----+--------+
| id | name |
+----+--------+
| 1 | john |
| 2 | Bryan |
| 3 | Princy |
| 5 | Danny |
+----+--------+
If I insert anothe row insert into demo_table values(4,"Michael").The table will be like
+----+---------+
| id | name |
+----+---------+
| 1 | john |
| 2 | Bryan |
| 3 | Princy |
| 4 | Michael |
| 5 | Danny |
+----+---------+
But I need the table to be like
+----+---------+
| id | name |
+----+---------+
| 1 | john |
| 2 | Bryan |
| 3 | Prince |
| 5 | Danny |
| 4 | Michael |
+----+---------+
I want the row to be concatenated to the table i.e.,
The rows of the table should be in the order of insertion.Can anybody suggest me the query to get it.Thank you for any answer in advance.

There is in general no internal order to the records in a MySQL table. The only order which exists is the one you impose at the time you query. You typically impose that order using an ORDER BY clause. But there is a bigger design problem here. If you want to order the records by the time when they were inserted, then you should either add a dedicated column to your table which contains a timestamp, or perhaps make the id column auto increment.
If you want to go with the latter option, here is how you would do that:
ALTER TABLE demo_table MODIFY COLUMN id INT auto_increment;
Then, do your insertions like this:
INSERT INTO demo_table (name) VALUES ('Michael');
The database will choose an id value for the Michael record, and in general it would be greater than any already existing id value. If you need absolute control, then adding a timestamp column might make more sense.

Just add another Column Created (Timestamp) in your table to store the time of insertion
Then use this Command for insertion
insert into demo_table id, name,created values(4,"Michael",NOW())
The NOW() function returns the current date and time.
Since you are recording the timestamp, it can be also used for future reference too

It's not clear why you want to control the "order" in which the data is stored in your table. The relational model does not support this; unless you specify an order by clause, the order in which records are returned is not deterministic.. Even if it looks like data is stored in a particular sequence, the underlying database engine can change its mind at any point in time without breaking the standards or documented behaviours.
The fact you observe a particular order when executing a select query without order by is a side effect. Side effects are usually harmless, right up to the point where the mean feature changes and the side effect's behaviour changes too.
What's more - it's generally a bad idea to rely on the primary key to have "meaning". I assume your id column represents a primary key; you should really not rely on any business meaning in primary keys - this is why most people use surrogate keys. Depending on the keys indicating in which order a record was created is probably harmless, but it still seems like a side effect to me. In this, I don't support #TimBiegeleisen's otherwise excellent answer.
If you care about the order in which records were entered, make this explicit in the schema by adding a timestamp column, and write your select statement to order by that timestamp. This is the least sensitive to bugs or changes in the underlying logic/database engine.

Related

MySQL Left Join / explain why original order of first table not been kept? [duplicate]

i have a mysql db with a table 'difficulties' with a few records. If i do "select * from difficulties" i get them back in the order they were added, ordered by primary key id:
mysql> select * from difficulties;
+----+-------+-----------+--------+----------+-----------+
| id | value | name | letter | low_band | high_band |
+----+-------+-----------+--------+----------+-----------+
| 1 | 1 | very_easy | VE | 1 | 1 |
| 2 | 2 | easy | E | 2 | 5 |
| 3 | 3 | medium | M | 6 | 10 |
| 4 | 4 | hard | H | 11 | 12 |
| 5 | 0 | na | NA | 0 | 0 |
+----+-------+-----------+--------+----------+-----------+
However, if i do "select name from difficulties" i get them back in a different order:
mysql> select name from difficulties;
+-----------+
| name |
+-----------+
| easy |
| hard |
| medium |
| na |
| very_easy |
+-----------+
My question is: what determines this order? Is there any logic to it? Is it something like "the order the files representing the records happen to be in within the filesystem" or something else that is to all intents and purposes random?
thanks, max
This is correct and by design: if you don't ask for sorting, the server doesn't bother with sorting (sorting can be an expensive operation), and it will return the rows in whatever order it sees fit. Without a requested order, the way the records are ordered can even differ from one query to the next (although that's not too likely).
The order is definitely not random - it's just whatever way the rows come out of the query, and as you see, even minor modifications can change this un-order significantly. This "undefined" ordering is implementation dependent, unpredictable and should not be relied upon.
If you want the elements to be ordered, use the ORDER BY clause (that's its purpose) - e.g.
SELECT name FROM difficulties ORDER BY name ASC;
That will always return the result sorted by name, in ascending order. Or, if you want them ordered by the primary key, last on top, use:
SELECT name FROM difficulties ORDER BY id DESC;
You can even sort by function - if you actually want random order, do this (caveat: horrible performance with largish tables):
SELECT name FROM difficulties ORDER BY RAND();
For more details see this tutorial and the documentation.
As Piskvor said, MySQL will order the query however it finds most convenient. To address the "why" part of your question, the different result orders are probably a side effect of different execution plans. If you have an index on difficulties, the second query would make use of it but the first would not.
Without the ORDER BY clause, the results are returned in random order. However, it seems logical to me that the easiest (and the fastest) way for db engine to return data as it's stored. So it's why the fist resultset is ordered by PK (no fragmentation, logical order is the same as physical). In the second case I would assume that you have an index on field name, and for the query select name from difficulties this index is covering, so db engine scans this index, and it's why you see results ordered by name. Anyway, you shouldn't rely on such "default" ordering.
select name from difficulties should return the values in alphabetical order as it is a text field.
And select * from difficulties will return in numeric order i believe. dont hold me to that lol
best thing to do is use ORDER BY if you care about what order things are

Avoid Duplicate Records with BeforeChange Table Event

I have a situation in MS Access database that I must prevent duplicate records based on combination of three attributes:
StudentNumber
ColleagueID
TypeOfAttending
So, for one combination (StudentNumber & ColleagueID) I have three types of attending: A, B and C.
Here is an example:
+---------------+-------------+---------------+
| StudentNumber | ColleagueID | AttendingType |
+---------------+-------------+---------------+
| 100 | 10 | A |
| 100 | 10 | B |
| 100 | 10 | C |
| 100 | 11 | A |
| 100 | 11 | B |
| 100 | 11 | C |
| 100 | 11 | C |
+---------------+-------------+---------------+
So last row would not be acceptable.
Does anyone have any idea?
As noted, you could choose all 3 as a PK. Or you can even create a unique index on all 3 columns. These two ideas are thus code free.
Last but least, you could use a Before change macro,and do a search (lookup) in the table to check if the existing record exists. So far, given your information, likely a unique index is the least effort, and does not require you to change the PK to all 3 columns (which as noted is a another solution).
So, you could consider a before change macro. And use this:
Lookup a Record in MyTable
Where Condition = [z].[Field1]=[MyTable].[Field1] And
[z].[Field2]=[MyTable].[Field2] And
[z].[ID]<>[MyTable].[ID]
Alias Z
RaiseError -123
Error Description: There are other rows with this data
So, you can use a data macro, use the before change table macro. Make sure you have the raise error code indented "inside" of the look up code. And note how we use a alias for the look up, since the table name (MyTable) is already in context, and is already the current row of data, so we lookup using "z" as a alias to distinguish between the current row, and that of lookup record.
So, from a learning point of view, the above table macro can be used, but it likely less work and effort to simply setup a uniquie index on all 3 columns.

Over 2500 tables in mysql

My application stores login information of over 2500 employees in a table named "emp_login".
Now I have to store the activities of every employee on daily basis. For this purpose i have created a separate table for every employee. E.g. emp00001, emp0002... Each table will have about 50 columns.
After digging in alot on stackoverflow I'm kind of confused. Many of the experts say that database having more than 200-300 tables on mysql is considered to be poorly designed.
My question is whether it is good idea to have such a bulk of tables? Is my database poorly designed? Should i choose other database like mssql? Or some alternative idea is there to handle the database of such applications??
Do -not- do it that way. Every employee should be in 1 table and have a primary key index ID ie:
1: Tom
2: Pete
You then assign the actions with a column that references the employees ID number
Action, EmployeeID
You should always group identical entities in a table with index ids and then link properties / actions to those entities by Id. Imagine what you would have to do to search a database that consisted of a different table for every employee. Would defeat the whole point of using SQL.
Event table could look like:
Punchin, 1, 2018/01/01 00:00
That would tell you Tom punched In at 2018/01/01 00:00. This is a very simple example, and you prob wouldn’t wanna structure an event table that way but it should get you on the right track.
This is nothing to do with MySQL but to do with your design which is flawed. You should have one table for all your employees. This contains information unique to the employees such as firstname, lastname and email address.
|ID | "John" | "Smith" | "john.smith#gmail.com" |
|1 | "James" | "Smith" | "james.smith#gmail.com" |
|2 | "jane" | "Jones" | "jane.jones.smith#yahoo.com" |
|3 | "Joanne" | "DiMaggio" | "jdimaggio#outlook.com" |
Note the ID column. Typicially this would be an integer with AUTO_INCREMENT set and you would make it the Primary Key. Then you get a new unique number every time you add a new user.
Now you have separate tables for every piece of RELATED data. E.g. the city they live in or their login time (which I'm guessing you want from the table name).
If it's a one to many relationship (i.e. each user has many login times), you create a single extra table which REFERENCES your first table. This is a DEPENDENT table. Like so:
| UserId | LoginTime |
| 1 | "10:00:04 13-09-2018" |
| 2 | "11:00:00 13-09-2018" |
| 3 | "11:29:07 14-09-2018" |
| 1 | "09:00:00 15-09-2018" |
| 2 | "10:00:00 15-09-2018" |
Now when you query your database you do a JOIN on the UserId field to connect the two tables. If it were only their LAST login time, then you could put it in the user table because it would be a single piece of data. But because they will have many login times, then login times needs to be its own table.
(N.b. I haven't put an ID column on this table but it's a good idea.)
If it's data that ISN'T unique to the each user, i.e. it's a MANY to MANY relationship, such as the city they live in, then you need two tables. One contains the cities and the other is an INTERMEDIARY table that joins the two. So as follows:
(city table)
| ID | City |
| 1 | "London" |
| 2 | "Paris" |
| 3 | "New York" |
(city-user table)
| UserID | CityID |
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
Then you would do two JOINS to connect all three tables and get which city each employee lived in. Again, I haven't added an ID field and PRIMARY KEY to the intermediary table because it isn't strictly necessary (you could create a unique composite key which is a different discussion) but it would be a good idea.
That's the basic thing you need to know. Always divide your data up by function. Do NOT divide it up by the data itself (i.e. table per user). The thing you want to look up right now is called "Database Normalization". Stick that into a search engine and read a good overview. It wont take long and will help you enormously.

Dynamic value to display numbers of entries in second table

I've got multiple entries in table A and would like to display the number of entries in a coloumn of table B. Is there a way to create a dynamic cell-content displaying the number of entries in a table?
I'm a beginner in MySQL and did not find a way to do it so far.
Example table A:
+----+------+------------+
| id | name | birthday |
+----+------+------------+
| 1 | john | 1976-11-18 |
| 2 | bill | 1983-12-21 |
| 3 | abby | 1991-03-11 |
| 4 | lynn | 1969-08-02 |
| 5 | jake | 1989-07-29 |
+----+------+------------+
What I'd like in table B:
+----+------+----------+
| id | name | numusers |
| 1 | tblA | 5 |
+----+------+----------+
In my actual database there is no incrementing ID so just taking the last value would not work - if this would've been a solution.
If MySQL can't handle this the option would be to create some kind of cronjob on my server reading the number of rows and writing them into that cell. I know how to do this - just checking if there's another way.
I'm not looking for a command to run on the mysql-console. What I'm trying to figure out is if there's some option which dynamically changes the cell's value to what I've described above.
You can create a view that will give you this information. The SQL for this view is inspired by an answer to a similar question:
CREATE VIEW table_counts AS
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = '{your_db}';
The view will have the cells you speak of. As you can see, it is just a filter on an already existing table, so you might consider that this table information_schema.tables is the answer to your question.
You can do that directly with COUNT() for example SELECT COUNT(*) FROM TblA The you get all rows from that table. If you IDXs are ok then its very fast. If you write it to another table you have to make an request too to get the result of the second table. So i think your can do it directly.
If you have some performance problems there are some other possibilities like Triggers or Stored Procedures to calculate that result and save them in a memory table to get a better performance.

MySql Prevent/track duplicate field across multiple fields

I'm looking for an easy way to check across multiple part tables to determine if a given part number is already present before adding it to a given table.
The current best idea I have come up with is a secondary table that simply lists every PN from all tables in a single column with a unique key; however I was wondering if there is a way to do it without creating a new table and index?
For the visual learner types, I have forty-some tables that more or less follow this pattern:
Table 1
| id | PN | Other Columns |
----------------------------------------------
| 1 | SomePn | ... ... ... ... |
...
Table 2
| id | PN | Still Other Columns |
--------------------------------------------------
| 1 | OtherPn | ... ... ... ... ... |
...
and about forty more as above, with up to 50 columns and up to 8 million records per table.
The goal is, whether through software (Java) or MySql rejecting the records, to prevent duplicate part numbers from creeping in across multiple tables. Is a master PN table the only possible or reasonable solution?
I know that the data structure is not the best design, and a rework is in progress, but I would like to know some suggested best practices as well as suggested solutions for this problem.
Adding a table is your best option.
Table 1:
| t1_id | PN | Other Columns |
----------------------------------------------
| 1 | pn_id | ... ... ... ... |
...
Table 2:
| t2_id | PN | Other Columns |
----------------------------------------------
| 1 | pn_id | ... ... ... ... |
...
Table 3:
| pn_id | PN |
------------------
| 1 | ## |
...
Although this may not be the easiest to implement solution in your case, it is the best overall solution, as you will have no scaling problems now or in the future. If you instead opted for a solution which checked all the tables for duplicate part numbers on update/creation, this would take longer and longer as your tables got bigger.
If you could guarantee that they would never get bigger or you would never add part numbers, you could probably get away with just writing a script to check for duplicates once and not worry about another table at all. But, in the long run, you'll want to add another table just to keep track of the part numbers.