MySQL: Adding a sort column - php

I'm looking to add a sort INT UNSIGNED field to my table so I can sort the items depending on their order without touching their id. Is it possible to give this column a value much like auto_increment but instead of incrementing by 1, MySQL increments by 10 or 20 or even 30? The large gaps allow me to shuffle their order.
I may be thinking about this the wrong way so please tell me what you think.

In fact, there is absolutely no need in "large gaps".
You can always swap 2 numbers - that's enough for the user-defined sorting.
Just update your sorting field to the same value with id initially and then move it to whatever position.

You can do that by changing auto_increment_increment:
SET ##auto_increment_increment=10;
More information

There is one issue: typically, for each table there can be only one column with auto_increment - if you have an id column that's also auto_increment - which really have much better reason to be auto_increment, this whole idea won't cut.
Secondly, it probably does not make much sense any way, since there is no reason for the latest inserted row (by default) to have the highest sorting order.

appart from setting the autoincrement to 10 like suggested you should also consider make it a unique key to speed up sorting.

Related

Reserving a set of ids in autoincremented column

I have a table with autoincremented columnd 'id'.
The current AUTO_INCREMENT value is 99. So the next element, inserted to this table will have id=99.
I need to add a 1000 rows, forcing their ids to 2000-3000, and then reserve these values to not mess with others. I mean, after inserting these rows, I would like to return AUTO_INCREMENT value to 99, so that next row will have value 99, after that 100 and so on.
Regular ids will not raise higher than 1000, so I want them to get incremented in normal way.
I know it looks not so elegant, but it would make things a lot easier for a particular task.
Is is possible at all?
I need to add a 1000 rows, forcing their ids
Nope, You Don't
Autoincrement field is not what you think. It's unique identifier that's have no particular meaning at all. So - just leave it alone. If you want some sort of meaningful identifier - add another field and play with it whatever way you want.
Is is possible at all?
Fortunately - no.

PHP/MySQL/PDO Library - Distributing Information Out Of A Database? What's the most efficient way?

I have keys for a project I made where I am trying to test a licensing system (Just for fun, and learning) a part that I thought I'd run into, is how to distribute the keys. I have about 100 keys in a database, and I'm trying to figure out the best way to distribute them. The database is layed out as follows,
ID (Auto Increment) | key
Using the PDO library, what is the most effective way to either to go in chronological order by ID? But even if I did chronological order, when I deleted the key that was given out, how would I go in chronological order? Or maybe random ID number? I have no clue how to go about the most effective way to distribute these keys?
If I understand your question correctly...
You might try this query through PDO:
SELECT * FROM `table-name`
ORDER BY `ID` ASC
Then when you step through the rows in a while() loop from the execution's return, it will be in chronological order like you asked.
As far as losing ID's, like if you delete the key with ID # 10, your table will jump from 9 to 11 in the returned rows IDs. When you add a new key, # 10 will not be used unless you specifically specify that ID when inserting.
EDIT: From the phrasing of your question, it sounds like you may be concerned about how you set up the ID's for the keys. Maybe you understand this already, but since you have Auto Increment, your IDs will be automatically generated when you insert new keys, so a new key would be assigned an ID of (ID of last inserted key) + 1.
Chronology isn't exactly a feature of PDO, or for that matter whatever database driver you are using... it's more a matter of your schema.
Typically, a commonly employed field in any database structure is a "timestamp" or "created" field that holds the time the record was created in the database. These fields can be MySQL datatype TIMESTAMP (in which case the driver will return seconds since the Unix Epoch), or DATETIME (in which case most drivers will attempt to return the language's native DateTime object if one exists.) Even though monotonically-increasing primary keys imply a certain amount of chronological order when sorted, a timestamp field can record the exact time a record was created at the server, as well as update on change using ON UPDATE CURRENT_TIMESTAMP. So I would suggest adding this to your schema.
With such a field in your database, you can always sort your queries using:
SORT BY timestamp_field_name ASC
Also, if by "distribute" you mean some data will be publicly accessible by using this key as query param of some sort, I wouldn't use the monotonic primary key for the exact reason you described, especially if this is a "licensing" proof of concept, which if you mean a DRM-type thing should probably produce a complex string. Hashed timestamps in a UNIQUE field, or the php uniqid function can produce values that can be stored in a VARCHAR database field with the UNIQUE key restraint. This is if I have understood your described goal.

ID's in phpmyadmin

I have a table in my phpmyadmin that contains some data for items that will be posted on a website. I'm adding these rows to the database manually. I want to show the number of the posted item. The first one will be '1', second one will be '2', etc. However if I use auto increment and delete the 2nd row there will be a gap in between. Suggestions to fix this?
I used PHP to display the ID of the row but when the second is deleted it shows the gap.
The structure starts with a column named 'id' which has a primary key and auto increment.
You don't want to do that! Period. You'll create yourself a lot of problems.
Your real issue is somewhere else. You think not having gaps between your ids will solve it. Solve that problem differently but leave the autoincremented id column alone. It is being implemented like that for a reason. The autoincrement makes sure you will never confuse two entries, it doesn't matter if there are gaps, you can always sort, you can always identify! If you need nice straight numbers, store your entries in a numeric array and use the keys for numbering. Or loop over your entries with a for loop and use the incrementor for numbering, or introduce an order column in your database.
Suggestions to fix this?
It's not broken!
You should not care or consider database ids as a developer, it is for internal use and data integrity.
If you really want to use incrementing numbers without gaps, use this in your query:
LIMIT 1 OFFSET X
Where X is the "id" in your url (not the real id).
However, listen to the folks here that are advising against this. It's not a very good idea and trust me, no one will care or even notice the forward facing database ids.

MySql using primary index instead of multiple column one!

Ok so I've a SQL query here:
SELECT a.id,... FROM article AS a WHERE a.type=1 AND a.id=3765 ORDER BY a.datetime DESC LIMIT 1
I wanted to get exact article by country and id and created for that index with two columns type and id. Id is also primary key.
I used the EXPLAIN keyword to see which index is used and instead of the multiple column index it used primary key index, but I did set the where stuff exactly in order as the index is created.
Does MySQL use the primary key index instead of the multiple column index because the primary one is faster? Or should I force MySql to use the multiple column index?
P.S. Just noticed it was stupid to use order when there is 1 result row. Haha. It increased the search time for 0.0001 seconds. :P
I don'e KNOW, but I would THINK that the primary key index would be the fastest available. And if it is, there's not much use using any other index. You're either going to have a article with an id of 3765 or you're not. Scanning that single row to determine if the type matches is trivial.
If you're only returning one row, there's no point to your ORDER BY clause. And the only point to the a.type=1 is to reject an article with the right id if the type is not correct.
MySQL allows for up to 32 indexes for each table, and each index can incorporate up to 16 columns. A multiple-column / composite index is considered a sorted array containing values that are created by concatenating the values of the indexed columns. MySQL uses multiple-column indexes in such a way that queries are fast when you specify a known quantity for the first column of the index in a WHERE clause, even if you do not specify values for the other columns.
If you look very carefully in how MySQL uses indexes, you will find that indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows.
In MySQL, a primary key column is automatically indexed for efficiency, as they use the in-built AUTO_INCREMENT feature of MySQL. On the other hand, one should not go overboard with indexing. While it does improve the speed of reading from databases, it slows down the process of altering data in a database (because the changes need to be recorded in the index). Indexes are best used on columns:-
that are frequently used in the WHERE part of a query
that are frequently used in an ORDER BY part of a query
that have many different values (columns with numerous repeating values ought not to be indexed).
So I try to use the primary key if my queries can suffice its use. When & only when it is required for more such indexing & fastness of fetching records, do I use the composite indexes.
Hope it helps.
The primary key is unique, so there's no need for MySQL to check any other index. a.id=3765 guarantees that there will be no more than one row returned. If a.type=1 is false for that row, then nothing will be returned.

What's the standard way to determine the number for a primary key?

I'm planning to make a very simple program using php and mySQL. The main page will take information and make a new row in the database with that information. However, I need a number to put in for the primary key. Unfortunately, I have no idea about the normal way to determine what umber to use. Preferably, if I delete a row, that row's key won't ever be reused.
A preliminary search has turned up the AUTOINCREMENT keyword in mySQL. However, I'd still like to know if that will work for what I want and what the common solution to this issue is.
In MySQL that's the standard solution.
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
Unless you have an overriding reason to generate your own PK then using the autoincrement would be good enough. That way the database manages the keys. When you are inserting a row you have to leave out the primary key column.
Say you have a table table = (a, b, c) where a is the primary key then the insert statement would be
insert into table (b, c) values ('bbb', 'ccc')
and the primary key will be auto inserted by the databse.
AUTOINCREMENT is what you want. As long as you don't change the table's settings, AUTOINCREMENT will continue to grow.
AUTOINCREMENT is the standard way to automatically create a unique key. It will start at 1 (or 0, I can't remember and it doesn't matter) then increment with each new record added to the table. If a record is deleted, its key will not be reused.
Auto increment primary keys are relatively standard depending on which DBA you're talking to which week.
I believe the basic identity integer will hit about 2 billion rows(is this right for mySQL?) before running out of room so you don't have to worry about hitting the cap.
AUTO_INCREMENT is the common choice, it sets a number starting from 1 to every new row you insert. All the work of figuring out which number to use is done by the db, you just ask it back after inserting if you need to ( in php you get it by callin mysql_last_insertid I think )
For something simple auto increment is best. For something more complicated that will ultimately have a lot of entries I generate a GUID and insert that as the key.

Categories