I am developing an web application where I have to give every new registrant a serial number. The main issue is with 'how to ensure uniqueness?'. I have searched through the different functions available with mysql and found mysql_insert_id() to be the fittest solution here. But before I run towards it, I need to know whether this function is thread-free. To more precise, say there are two users sitting at two different terminals and submits the registration form synchronously. Will they both get the same id out of the execution of the function mysql_insert_id()? Otherwise, my project will spoil. Please help. If I could not clear my point, please comment. Thanks in advance.
here is detailed solution
CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)
By default, the starting value for AUTO_INCREMENT is 1, and it will increment by 1 for each new record.
To insert a new record into the "Persons" table, we will NOT have to specify a value for the "ID" column (a unique value will be added automatically):
If you have an id column on your table in your database and that column is set to be the primary key that will be enough. Even if 2 people will submit the form at the same the ids will be unique.
id column could be defined like this
ADD PRIMARY KEY (`id`)
id` int(11) NOT NULL AUTO_INCREMENT
Alternatively, you can use the UUID() function in mysql.
A UUID is designed as a number that is globally unique in space and
time. Two calls to UUID() are expected to generate two different
values, even if these calls are performed on two separate computers
that are not connected to each other.
mysql> SELECT UUID();
-> '6ccd780c-baba-1026-9564-0040f4311e29'
For further details : http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_uuid
Related
I'm using php and i have a table that have 2 column of varchar , one is used for user identification, and the other is used for page name entry.
they both must be varchar.
i want to insert ignore data when user enter a page to know if he visited it or not, and i want to fetch all the rows that the user have been in.
fetch all for first varchar column.
insert if not exist for both values.
I'm hoping to do it in the most efficient way.
what is the best way to insert without checking with another query if exist?
what is the best way other then:
SELECT * FROM table WHERE id = id
to fetch when the column needed is varchar?
You should consider a normalized table structure like this:
CREATE TABLE user (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE page (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE pages_visted (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED,
page_id INT UNSIGNED,
UNIQUE KEY (user_id, page_id)
);
INSERT IGNORE INTO pages_visted (user_id, page_id) VALUES (:userId, :pageId);
SELECT page_id FROM pages_visted WHERE user_id = :userId;
I think you want to implement a composite primary key.
A composite primary key tells MySQL that you want your primary key to be a combination of fields.
More info here: Why use multiple columns as primary keys (composite primary key)
I don't know of a better option for your query, although I can advise, if possible:
Define columns to be NOT NULL. This gives you faster processing and requires less storage. It will also simplify queries sometimes because you don't need to check for NULL as a special case.
And with variable-length rows, you get more fragmentation in tables where you perform many deletes or updates due to the differing sizes of the records. You'll need to run OPTIMIZE TABLE periodically to maintain performance.
how to limit the number of entry in inserting data in mysql database using php to 1
Any suggestions? Thanks .
You probably can't get it right in PHP since the trip back and forth to the database leaves room for another part of your application to create an entry. Normally we achieve this sort of thing by putting a unique index on the table that prevents duplication of data. For example:
CREATE TABLE alf_mimetype
(
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL,
mimetype_str VARCHAR(100) NOT NULL,
PRIMARY KEY (id),
UNIQUE (mimetype_str)
) ENGINE=InnoDB;
If you attempt to insert a row with duplicate mimetype_str, the database will generate an exception. Catch it in your application and you'll know that your single entry for that particular row is already there.
You can create UNIQUE keys on multiple columns as well. Your primary key also represents a unique constraint and can consist of multiple columns.
I have the following schema with the following attributes:
USER(TABLE_NAME)
USER_ID|USERNAME|PASSWORD|TOPIC_NAME|FLAG1|FLAG2
I have 2 questions basically:
How can I make an attribute USER_ID as primary key and it should
automatically increment the value each time I insert the value into
the database.It shouldn't be under my control.
How can I retrieve a record from the database, based on the latest
time from which it was updated.( for example if I updated a record
at 2pm and same record at 3pm, if I retrieve now at 4pm I should get
the record that was updated at 3pm i.e. the latest updated one.)
Please help.
I'm assuming that question one is in the context of MYSQL. So, you can use the ALTER TABLE statement to mark a field as PRIMARY KEY, and to mark it AUTOINCREMENT
ALTER TABLE User
ADD PRIMARY KEY (USER_ID);
ALTER TABLE User
MODIFY COLUMN USER_ID INT(4) AUTO_INCREMENT; -- of course, set the type appropriately
For the second question I'm not sure I understand correctly so I'm just going to go ahead and give you some basic information before giving an answer that may confuse you.
When you update the same record multiple times, only the most recent update is persisted. Basically, once you update a record, it's previous values are not kept. So, if you update a record at 2pm, and then update the same record at 3pm - when you query for the record you will automatically receive the most recent values.
Now, if by updating you mean you would insert new values for the same USER_ID multiple times and want to retrieve the most recent, then you would need to use a field in the table to store a timestamp of when each record is created/updated. Then you can query for the most recent value based on the timestamp.
I assume you're talking about Oracle since you tagged it as Oracle. You also tagged the question as MySQL where the approach will be different.
You can make the USER_ID column a primary key
ALTER TABLE <<table_name>>
ADD CONSTRAINT pk_user_id PRIMARY KEY( user_id );
If you want the value to increment automatically, you'd need to create a sequence
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
and then create a trigger on the table that uses the sequence
CREATE OR REPLACE TRIGGER trg_assign_user_id
BEFORE INSERT ON <<table name>>
FOR EACH ROW
BEGIN
:new.user_id := user_id_seq.nextval;
END;
As for your second question, I'm not sure that I understand. If you update a row and then commit that change, all subsequent queries are going to read the updated data (barring exceptionally unlikely cases where you've set a serializable transaction isolation level and you've got transactions that run for multiple hours and you're running the query in that transaction). You don't need to do anything to see the current data.
(Answer based on MySQL; conceptually similar answer if using Oracle, but the SQL will probably be different.)
If USER_ID was not defined as a primary key or automatically incrementing at the time of table creation, then you can use:
ALTER TABLE tablename MODIFY USER_ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT;
To issue queries based on record dates, you have to have a field defined to hold date-related datetypes. The date and time of record modifications would be something you would manage (e.g. add/change) based on the way in which you are accessing the records (some PHP-related way? it's unclear what scripts you have in play, based on your question.) Once you have dates in your records you can ORDER BY the date field in your SELECT query.
Check this out
For your AUTOINCREMENT, Its a question already asked here
For your PRIMARY KEY use this
ALTER TABLE USER ADD PRIMARY KEY (USER_ID)
Can you provide more information. If the value gets updated you definitely do NOT have your old value that you entered at 2pm present in the dB. So querying for it will be fine
You can use something like this:
CREATE TABLE IF NOT EXISTS user (
USER_ID unsigned int(8) NOT NULL AUTO_INCREMENT,
username varchar(25) NOT NULL,
password varchar(25) NOT NULL,
topic_name varchar(100) NOT NULL,
flag1 smallint(1) NOT NULL DEFAULT 0,
flag2 smallint(1) NOT NULL DEFAULT 0,
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
For selection use query:
SELECT * from user ORDER BY update_time DESC
I have a create database and have about 8 tables in Database also created Primary keys and foreign-keys in appropriate tables. But when I insert data in primary-table, my other table doesn't show updated data.
I mean, say I have a table which has data for names like ;
N is (name)
N1 = George, N2 = Ross, N3 = Rim ...etc now that means i have Primary key N1,N2,N3 etc..
Now, when I insert this primary keys in others table it should shows me name like George, ross and rim instead of primary-key number it self(N1,N2,N3).
How can I get names instead PK itself?
You are misunderstanding the concept of keys in relational databases. Keys are there, not to copy data from similar tables but to show the relations between data in different tables. They help to understand how the data between different tables is related - that is where the name "relational database" comes from. They also speed up querying of that data if indexed.
You can read more about the usage of keys here: Keys and normalization
I am still unclear on what exactly you want to do with the database. but let me demonstrate you on the basic of database and how you should be using it. Consider a table users where you will be storing the data related to user.
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`email` varchar(50) DEFAULT NULL,
`phone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
);
the column id holds the primary key and have an attribute called auto_increment, now what this means is every time you insert a record to this table the id attribute gets incremented and you don't have to worry about inserting any value in this column because your database will take care of that. for example take a look at insert query below.
INSERT INTO users(name,email,phone) VALUES('First Name', 'first#domain.com', '9999999999');
INSERT INTO users(name,email,phone) VALUES('Second Name', 'second#domain.com', '8888888888');
INSERT INTO users(name,email,phone) VALUES('Third Name', 'third#domain.com', '2222222222');
INSERT INTO users(name,email,phone) VALUES('Fourth Name', 'fourth#domain.com', '3333333333');
did you see you did not insert any id here. this is because it is database who will handle the logic. now the first record will hold the value 1 the second will have 2 the third one 3 and the fourth one 4 and so on.
hope this helps you.
So I am working on a fairly small script for the company I work at the help us manage our servers better. I don't use MySQL too often though so I am a bit confused on what would be the best path to take.
I am doing something like this...
$sql = "CREATE TABLE IF NOT EXISTS Servers
(
MachineID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(MachineID),
FirstName varchar(32),
LastName varchar(32),
Datacenter TINYINT(1),
OperatingSystem TINYINT(1),
HostType TINYINT(1)
)";
$result = mysql_query($sql,$conn);
check ($result);
$sql = "CREATE TABLE IF NOT EXISTS Datacenter
(
DatacenterID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(DatacenterID),
Name varchar(32),
Location varchar(32)
)";
$result = mysql_query($sql,$conn);
check ($result);
Basically inside the Servers table, I will be storing the index of an entry in another table. My concern is that if we remove one of those entries, it will screw up the auto incremented indexes and potentially cause a lot of incorrect data.
To explain better, lets say the first server I add, the Datacenter value is 3 (which is the DatacenterID), and we remove the id 1 (DatacenterID) Datacenter at a later time.
Is there a good way to do this?
Auto increment only has an effect on inserting new rows into a table. So you insert three records into database and they get assigned ids of 1, 2, and 3. Later you delete id 1, but the records at id 2 and 3 are unchanged. This says nothing of any of the server records that might be trying to reference the database id 1 record though that is now missing.
as said by paul, it is safe to remove old row and add another new one later. The auto incremental index won't be affected by deletion.
But I would suggest instead of removing them, simply add a column 'status' and set 0, implying they are no longer in use, to keep any possible record in db.
Servers.Datacenter should be an INT, too, as you would store the DataCenterID in this field. Then, nothing will be mixed up when you remove some Datacenter from the second table.
If you remove in the way you suggest nothing will happen. auto-increment will just add the next highest number in sequence whenever a new record is added and so will not affect any previous records.
Hope that helps.