how to maintain a continuous id number row count in mysql - php

i have an id coloumn which is integer and auto incremented type.
The problem is when ever i delete a row the continuity of the number breaks.
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Behance | 2 |
| Techcrunch | 3 |
| flipkart | 4 |
+----------------------+----+
FOR EXAMPLE if i delete the row with id=2, then i output in id will be
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Techcrunch | 3 |
| flipkart | 4 |
+----------------------+----+
but i want it to be like :
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Techcrunch | 2 |
| flipkart | 3 |
+----------------------+----+
How to do it ??

To directly answer your question, here's how you fix those gaps in sequential numeric fields: Fixing gaps in mysql table row id after we delete some of them
But let's be careful here for a moment.
Let's assume id is your primary key. ID's are usually the point of reference to an object, because auto-generated ID's are unique. Call it a convention.
That means that If ANY part of your code depends on the id column, your application will break.
If you NEED to do this, then use some other field as main reference. Perhaps an unique name field or something similar.
If ID is NOT your primary key, then you probably should've chosen another name for it to begin with. Anyway, in this case, the chances of you breaking anything are much smaller.
Notice that I said smaller, but not zero. We don't know your application, so it's possible that your code uses id for something important, and that'll mean trouble for you.

Related

How to identify which table to delete a record when data coming from two tables?

I have two tables where some same kind of information kept. One table has approved information and other one contains pending(waiting for approval) data. I fetch data from both table and display in a same view. So user will see data from both the tables. User can delete those records. But when deleting I've a trouble with finding out which table I should delete.
Assume, table1(Approved info), table2(Pending info)
table1
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 100 |
11 | test2 | N/A | 100 |
12 | test3 | N/A | 101 |
13 | test4 | N/A | 200 |
table2
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 105 |
11 | test2 | N/A | 103 |
12 | test3 | N/A | 106 |
13 | test4 | N/A | 202 |
table1 has a record with id of 10; and table2 has a record with id of 10 in that table. Id is the primary key of both tables. Both record will show to user. Let's say user wants to delete the record related to id 12 came from table2. So I want to delete that record from table2. But how can I figure out which table to delete that record. Because I can't use id to figure out the table. I have tried using some kind of data attribute attached with
data coming from table2 to differentiate them. But anyone can change them by inspecting it. So what is the proper way for solve this issue?
On any case, on any system, makes sense to have two to tables with same columns. That should be one of the firsts rules of database design. What's more, you discovered yourself how hard is to maintain a design like that. I see this on legacy systems developed with zero love to the code. In the future this will turn into a snowball. You should change it as soon as possible.
status column
The status of and entity or resource, is classic requirement, usually implemented with one little column which called : status, flag, mode, etc. In your case, it could have these values (#BhaumikPandhi comment):
pending/approved/rejected
id | name | description | creator | status |
--------------------------------------------
10 | test1 | N/A | 100 | pending|
If you are worried to the database optimization, you could use a tinyint with these equivalence in your documentation:
1 = pending
2 = approved
3 = rejected
status table
You could keep your first table called record
id | name | description | creator |
And create another one called record_status with 2 columns, in which record_id is a FK of record table
record_id | status |
Anyway, the status column is the most easy a classic approach to your requirement.

How to use insert and update with no primary key

I have the following Mysql-table:
+-------+--------+------------+----+-------+
| Name | Number | Department | id | JobID |
+-------+--------+------------+----+-------+
| Sven | 2204 | Marketing | 10 | 111 |
| Peter | 2304 | IT | 20 | 222 |
| Bjorn | 4409 | IT | 30 | 333 |
+-------+--------+------------+----+-------+
I get the three columns: Name, Number, Department from a system where I don't have the id and need to perform something in my php script.
Now I would like to performa an insert if there is a new record. If there is an existing record I would like to perform an update, if something changed like Name, Number or Department.
For example, if Number changes it should compare Name and Department and then change number. If Departmend changes it should compare Name and Number and then change Department and so on.
The problem is, that I can not use insert...on duplicate key, because I don't get the primary key.
If I use Replace Into it deletes me also the entry for JobID. Is there a solution how to perform a sql that it will insert and also update if there is now entry? Or something that can do the trick?
Thanks for your help!

Database design with undetermined data

Recently I have been planning a system that allows a user to customize and add to a web interface. The app could be compared to a quiz creating system. The problem I'm having is how to design a schema that will allow for "variable" numbers of additions to be made to the application.
The first option that I looked into was just creating an object for the additions and then serializing it and putting it in its own column. The content wouldn't be edited often so writing would be minimal, reads however would be very often. (caching could be used to cut down)
The other option was using something other than mysql or postgresql such as cassandra. I've never used other databases before but would be interested in learning how to use them if they would improve the design of the system.
Any input on the subject would be appreciated.
Thank you.
*edit 29/3/14
Some information on the data being changed. For my idea above of using a serialized object, you could say that in the table I would store the name of the quiz, the number of points the quiz is worth and then a column called quiz data that would store the serialized object containing the information on the questions. So overall the object could look like this:
Questions(Array):{
[1](Object):Question{
Field-type(int):1
Field-title(string):"Whats your gender?"
Options(Array):{"Female", "Male"}
}
[2](Object):Question{
Field-type(int):2
Field-title(string):"Whats your name?"
}
}
The structure could vary of course but generally i would be storing integers to determin the type of field in the quiz and then a field to hold the label for the field and the options (if there are any) for that field.
In this scenario I would advise looking at MongoDB.
However if you want to work with MySQL you can think about the entity-attribute-value model in your design. The EAV model allows you to design for entries that contain a variable number of attributes.
edit
Following your update on the datatypes you would like to store, you could map your design as follows:
+-------------------------------------+
| QuizQuestions |
+----+---------+----------------------+
| id | type_id | question_txt |
+----+---------+----------------------+
| 1 | 1 | What's your gender? |
| 2 | 2 | What's your name? |
+----+---------+----------------------+
+-----------------------------------+
| QuestionTypes |
+----+--------------+---------------+
| id | attribute_id | description |
+----+--------------+---------------+
| 1 | 1 | Single select |
| 2 | 2 | Free text |
+----+--------------+---------------+
+----------------------------+
| QuestionValues |
+----+--------------+--------+
| id | question_id | value |
+----+--------------+--------+
| 1 | 1 | Male |
| 2 | 1 | Female |
+----+--------------+--------+
+-------------------------------+
| QuestionResponses |
+----+--------------+-----------+
| id | question_id | response |
+----+--------------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | Fred |
+----+--------------+-----------+
This would then allow you to dynamically add various different questions (QuizQuestions), of different types (QuestionTypes), and then restrict them with different options (QuestionValues) and store those responses (QuestionResponses).

How to construct table with dynamic input fields?

I have a PHP script where you can (as admin) select how many input-fields there will be in a question form. Some of the fields are non optional, but som are (as many as you like).
The table in MySQL for collecting the answers looks like this:
id | userid | fname | ename | seat | optional
If the admin want it to be two optional input-fields then the result of one filled form would take three tows in the table:
| 5 | 3 | Peter | Pan | 4 | |
| | 3 | | | | opt.value1 |
| | 3 | | | | opt.value2 |
Is this really the best way to store this in? How would you solve it?
And also, how can I make shure that the userid is unique for the user? I can't use the auto-increment key value thing in MySQL because the same value is on three rows...
The way i learned it you have to use multiple tables. Like this:
Table1:
id | userid | fname | ename | seat
Table2:
userid | optional
Table2.userid is a reference to Table1.userid
Then the fields that has to be filed can be put into the first table and all the optional in the second.
If i follow your example your database should look like this:
Table1:
id | userid | fname | ename | seat
5 | 3 | Peter | Pan | 4
Table2:
userid | optional
3 | opt.value1
3 | opt.value2
By the way, why do you have both id and userid in Table1?
Best practice would be to store "id" and "optional" values in a separate table.
Then pull the information you want from it for each "id".

MySQL query how to get list of all distinct values from columns that contain multiple string values?

I am trying to get a list of distinct values from the columns out of a table.
Each column can contain multiple comma delimited values. I just want to eliminate duplicate values and come up with a list of unique values.
I know how to do this with PHP by grabbing the entire table and then looping the rows and placing the unique values into a unique array.
But can the same thing be done with a MySQL query?
My table looks something like this:
| ID | VALUES |
---------------------------------------------------
| 1 | Acadian,Dart,Monarch |
| 2 | Cadillac,Dart,Lincoln,Uplander |
| 3 | Acadian,Freestar,Saturn |
| 4 | Cadillac,Uplander |
| 5 | Dart |
| 6 | Dart,Cadillac,Freestar,Lincoln,Uplander |
So my list of unique VALUES would then contain:
Acadian
Cadillac
Dart
Freestar
Lincoln
Monarch
Saturn
Uplander
Can this be done with a MySQL call alone, or is there a need for some PHP sorting as well?
Thanks
Why would you store your data like this in a database? You deliberately nullify all the extensive querying features you would want to use a database for in the first place. Instead, have a table like this:
| valueID | groupID | name |
----------------------------------
| 1 | 1 | Acadian |
| 2 | 1 | Dart |
| 3 | 1 | Monarch |
| 4 | 2 | Cadillac |
| 2 | 2 | Dart |
Notice the different valueID for Dart compared to Matthew's suggestion. That's to have same values have the same valueID (you may want to refer to these later on, and you don't want to make the same mistake of not thinking ahead again, do you?). Then make the primary key contain both the valueID and the groupID.
Then, to answer your actual question, you can retrieve all distinct values through this query:
SELECT name FROM mytable GROUP BY valueID
(GROUP BY should perform better here than a DISTINCT since it shouldn't have to do a table scan)
I would suggest selecting (and splitting) into a temp table and then making a call against that.
First, there is apparently no split function in MySQL http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ (this is three years old so someone can comment if this has changed?)
Push all of it into a temp table and select from there.
Better would be if it is possible to break these out into a table with this structure:
| ID | VALUES |AttachedRecordID |
---------------------------------------------------------------------
| 1 | Acadian | 1 |
| 2 | Dart | 1 |
| 3 | Monarch | 1 |
| 4 | Cadillac | 2 |
| 5 | Dart | 2 |
etc.

Categories