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.
Related
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 had originally wanted my alarmID value to be the primary key and to be Auto incremented. But I have decided to make my Title value as so.
How can I manually auto increment alarmID so that every time I insert values, the alarmID value gets incremented by exactly 1.
I want a way to keep track of entries by when they were inserted to be display chronologically later on.
Here is how I have my php code.
$sql = "CREATE TABLE IF NOT EXISTS alarms (
alarmID INT NOT NULL,
PRIMARY KEY (Title),
Title CHAR(30) NOT NULL,
Description TEXT,
DT DATETIME
)";
Something like this should work, you still get a unique indexed title and the auto increment alarmID, it's much more subtle than using a mysql function / proc.
CREATE TABLE IF NOT EXISTS alarms (
alarmID MEDIUMINT NOT NULL AUTO_INCREMENT,
Title CHAR(30) NOT NULL,
Description TEXT,
DT DATETIME,
PRIMARY KEY (alarmID),
UNIQUE KEY title (Title)
);
Your best bet here would be to make alarmID an auto incrementing primary key and, if Title has to be unique, place a unique constraint on it.
Manually computing the new incremented ID could in fact lead to issues if multiple users use your system, so it is better to leave the job to the DBMS itself.
I am doing a web app for a client that is an internal system for getting employees to fill out a multitude of forms before they start.
When I have received the forms, there are lots of them like 25-30, and i am having trouble figuring out how to store the data for each of them in a MySQL database. Each of the forms have different data required and different selections.
Initially i was thinking of having a single table, then serializing the selections into a column rather than having a hundred columns. I haven't done anything of this magnitude before and wondered what the best way to save the data would be?
You can use an EAV store, something like:
| form_name | employee_id | field_name | value |
It's not super clean but it's kinda normalized and you'll be able to query on it in a sane fashion. If you run into issues with the table being too large, even with indexes, you can split up the EAV store into multiple tables, possibly by form_name.
You probably want at least three tables:
CREATE TABLE form_fields (
id INT NOT NULL AUTO_INCREMENT,
form_name VARCHAR(50),
field_name VARCHAR(20),
PRIMARY KEY (`id`),
UNIQUE KEY `real_pk` (`formname`,`fieldname`)
);
CREATE TABLE forms_completed (
id INT NOT NULL AUTO_INCREMENT,
form_name VARCHAR(20),
... other info about this instance of the form,
e.g. submitted date, submitted by...
PRIMARY KEY (`id`),
FOREIGN KEY (form_name) REFERENCES form_fields(form_name)
ON DELETE CASCADE
);
CREATE TABLE form_values (
id INT NOT NULL AUTO_INCREMENT,
form_instance IN NOT NULL,
form_name VARCHAR(50), /* only required to force referential integrity */
field_name VARCHAR(20),
date_value DATETIME,
int_value INT,
float_value FLOAT,
string_value VARCHAR(100),
PRIMARY KEY (`id`),
FOREIGN KEY (form_instance) REFERENCES forms_completed(id)
ON DELETE CASCADE,
FOREIGN KEY (form_name, field_name)
REFERENCES form_fields(form_name, field_name)
ON DELETE CASCADE
);
If you're not locked into MySQL, you can try doing this with MongoDB, as it is better suited for tasks like this one. If you are locked in, EAV is probably the way to go.
If you are using this Data for maintaining records its a better idea to use MS Excel.
Or even you can try with the MS Access as alternative to it.
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.
I want an id and name to be primary key for my table. I want to increment id with every insert, so i set it to auto_increment. The problem is when i insert into table a new entry with same name, it inserts it with a new id and there are duplicate entries with same name and different ids. I don't want to search the table beforehand to see if there is any entry beforehand. Please help me how to correct this problem.
I think you have done something like this
CREATE TABLE table1
id unsigned integer autoincrement,
name varchar,
....
primary key (id,name)
This primary key does not select on unique name, because the autoincrement id will always make the key as a whole unique, even with duplicate name-fields.
Also note that long primary keys are a bad idea, the longer your PK, the slower inserts and selects will execute. This is esspecially bad on InnoDB, because the PK is included in each and every secondary key, ballooning your index files.
Change it to this
CREATE TABLE table1
id unsigned integer autoincrement primary key,
name varchar,
....
unique index `name`(name)
If you want it to be unique by name, you need to add a unique index on the name field, and then you can use the mysql syntax for on duplicate key: mysql reference for on duplicate key
You could apply a unique index to your name field, or if you're storing people, allow duplicate names.
Add UNIQUE(your_column_name) where you should replace your_column_name with the column in your database.