How can i add multiple values to my table called 'courier'?
I need to add a second telephone number. The way i created table was:
create table kurier (
id_kurier int not null,
imie varchar(45) not null,
nazwisko varchar(45) not null,
telefon int not null,
id_rejon int,
nr_rej varchar(45) not null,
id_przelozony int,
constraint id_kurier primary key (id_kurier),
constraint id_przelozony foreign key (id_przelozony)
references kurier (id_kurier)
)
There are various options, among them few are as follows:
1- (Discouraged) Add another column to hold telphone2. (but in case you are going to have more numbers then you need more columns)
2- (BEST) Create a child table that stores telephones numbers per courier (as a foregin key). This can hold as many as you need. Move your initial data into child table, drop column from original table.
3- (Alternative) Use a separator to store multiple data as string for eg. using comma (,) the data will look like 99999999, 8888888, 77777777. You can then fetch and split values by the separator you chose for rendering and/or reporting purposes.
Hope this helps !
Related
I have the following tables:
movie
title - VARCHAR (255)
year - VARCHAR (4)
format - VARCHAR (255)
movie_custom
title - VARCHAR (255)
year - VARCHAR (4)
format - VARCHAR (255)
username_id - INT (11)
Each table has different data, but I want to ensure that there are no changes to some of the column names. For example, if I changed format - VARCHAR (255) to distribution_type - VARCHAR (30) on movie, I'd also want to make sure the same change gets made on movie_custom.
Is there any way to ensure this in MySQL? Somehow couple two columns together in some way?
This is too long for a comment.
It sounds like you have a lousy data model. If you fix the data model, you'll fix your problem.
You should have a movie database with a primary key:
create table movies (
movieId int primary key auto_increment,
. . .
);
Then, the second table should have three columns:
create table moviesCustom (
movieCustomId int primary key auto_increment,
movieId int not null,
username_id int,
constraint foreign key (movieId) references movies(movieId)
);
Then, when you want information in both tables, use a join.
Plan A
For title create a normalization table. Then, instead of VARCHAR(...), have MEDIUMINT UNSIGNED to link to that table.
Then when adding any title from anywhere (base or custom), look up the name in that table to get the id (or create a new id).
This is probably the only way to keep the datatype if title in a single location (and appease Gordon).
However, excessive use of this (ie, multiple columns done this way) will cost something in performance.
Suggestion: Change year VARCHAR(4) to year YEAR, since there is such a datatype.
Plan B
Combine the two tables; use a special username (perhaps NULL) as the 'base' entry.
I'm trying to create a shopping cart sort of DB, where users can checkout certain items and I would be able to see what items each person has and I would also be able to see who a specific item is checked out to.
I would also like to have an image for each item. (not sure how efficient that is?)
Currently I have something like this:
CREATE TABLE person(
id CHAR(9) NOT NULL PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
CREATE TABLE items(
id CHAR(9) NOT NULL PRIMARY KEY,
itemName VARCHAR(30) NOT NULL,
category VARCHAR(30) NOT NULL,
subcategory VARCHAR(30) NOT NULL,
image LONGBLOB
);
CREATE TABLE person_items(
personID CHAR(9) NOT NULL,
itemID CHAR(9) NOT NULL,
FOREIGN KEY (personID) REFERENCES person(id),
FOREIGN KEY (itemID) REFERENCES items(id)
);
Is this an efficient way to basically store an array of items that a person is allowed to check out, or are there better ways?
Also, is storing a LONGBLOB for an image a good idea or is there a better way to do that?
First of all your IDs in your tables should be INTEGERs. The relation table 'person_items' enables a n:m relation between person and items, which should be your goal, if I understood your question.
I suggest to save a path and the image file name in your db, so that you can get this value and use it as link or something similar in your app. I would not save the image as a blob cause you have a lot of unneccesary work with headers and so on. And if using a path in the db, you will easily be able to use different file formats. Just my opinion.
I have the following table with 1,000,000+ records:
CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`description` text,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
What I'd like to do is be able to fetch products with null description quickly - forget about empty string.
If I add a key by description, the whole description will be indexed and I don't want such a big index. I could indeed do:
ALTER TABLE products ADD KEY has_description (description(1));
This will create an index with only the first character. This is much better than having a "complete" index, but I'd like to know if there's a way to create a proper index - e.g. a boolean index, true/false depending on the product having a description or not respectively.
Additional requirement is not adding a new column with this value - that is trivial, but it's duplicated information I don't want to have in the table.
Already tried stuff like
ALTER TABLE products ADD KEY has_description (description IS NULL);
... but didn't work.
Can this be done at all?
You can only have Index on existing fields.
The answer is: no way
But you can add another Field (and Index for that) containing the description state (empty or not).
Use Insert and Update trigger to have that field always synced with description data.
I'd like to set up the following database scenario:
CREATE TABLE IF NOT EXISTS `points` (
`po_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`po_north` INT,
`po_east` INT,
PRIMARY KEY (`po_id`),
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `lines`(
`li_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`li_from` INT NOT NULL,
`li_to` INT NOT NULL,
PRIMARY KEY (`li_id`),
FOREIGN KEY (`li_from`) REFERENCES points(`po_id`),
FOREIGN KEY (`li_to`) REFERENCES points(`po_id`),
) ENGINE=InnoDB;
Now I want to set up a third table, that sores some metadata like who created or altered a point or a line:
CREATE TABLE IF NOT EXISTS `metadata` (
`me_type` ENUM('point','line') NOT NULL,
`me_type_id` INT UNSIGNED NOT NULL,
`me_permissions` VARCHAR(255) NOT NULL,
`me_created_by` INT UNSIGNED NOT NULL,
`me_created_on` DATETIME NOT NULL,
`me_last_modified_by` INT UNSIGNED NOT NULL,
`me_last_modified_by` DATETIME NOT NULL,
) ENGINE=InnoDB;
My first approach was to set an ENUM with two types (points and lines). But the problem is still, that I cannot properly reference a foreign key to one of the tables. Is there any recommended solution for such problem in MySQL?
BTW:
The fields for me_created_by and me_last_modified_by shall reference to a table storing some user data.
Your case appears to be yet another instance of the design pattern known as "generalization specialization" or perhaps "table design for class inheritance".
If you think of points and lines as classes of objects, they are both subclasses of some more general class of objects. I'm not sure what name to give the superclass in this case. Here's one of several previous questions that address the same issue.
Extending classes in the database
Fowler gives an extensive treatment of the subject. Your case has an added wrinkle, because you are dealing with metadata. But that need not alter the design. You need a third table, which I'll call "Items" for lack of a better term. The key, "it_id" would be assigned an auto number, and you would add an item every time you add either a point or a line. The two columns "po_id" and "li_id" would not be assigned an auto number. Instead they would be foreign keys, referencing "it_id" in the Items table.
The references to points or lines in the metadata table would then be references to "items" and you could use that information to find information about points or lines as the case may be.
How helpful this is depends on what you are trying to do with the metadata.
Your tables points and lines should contain a foreign key to metadata – not the other way around. Doing so will save you from defining any more complicated table setups. Using this approach, a single metadata-entry could be re-used several times for many different points or lines. This isn't even MySQL specific but a general, normalized database structure.
you can do this using a trigger, you need to trigger an event that can create reference key for either point or line before you insert a record based on respective tables
I have this database structure
CREATE TABLE `productinfo` (
`ProductID` int(11) NOT NULL AUTO_INCREMENT,
`ProductName` varchar(255) NOT NULL,
`ProductImage` varchar(255) NOT NULL,
`CategoryID` int(11) NOT NULL,
`SubCategoryID` int(11) NOT NULL,
`ProductBrief` varchar(255) NOT NULL,
`Features` text NOT NULL,
`Specifications` text NOT NULL,
`Reviews` text NOT NULL,
`Price` varchar(255) NOT NULL,
`Status` tinyint(4) NOT NULL,
PRIMARY KEY (`ProductID`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
I now I need to turn ProductID, CategoryID, and SubCategoryID into a string like Ps-5678 for the part number. ProductID is the primary key so how do i change the structure of the database. CategoryID, and SubCategoryID are primary keys in other tables so how do i handle this..is it as easy as turning
`ProductID` int(11) NOT NULL AUTO_INCREMENT
into a string..and getting rid of
PRIMARY KEY (`ProductID`)
ideas, suggestions anyone
Primary keys are for the database.
Display names are for end users.
Do not confuse one with another! Don't make a primary key out of something that has a meaning. You will regret it sooner or later.
Having a surrogate key / identity / autonumber as a primary key is a very good idea and is used widely in database design.
You can add a column or even a DERIVED COLUMN and add a unique constraint on it.
I believe it should be that easy.
however you need to determine what string type you want to use
http://dev.mysql.com/doc/refman/5.1/en/string-types.html
Your requirement is unclear. How do you get "PS-5678" fro 3 int columns ? There is only 2 components in your example.
Do you just need to CONVERT the 3 INTs to a single CHAR() string ?
If so, the database is fine, no need to change the table at all !?!?! The three components are already available, correctly seperated, as distinct columns. What you are looking for is merely DISPLAYING the three components as a single string.
It's not clear to me from your question just what you do to product, category, and subcategory to make your part number. I'll assume for the sake of argument that you are concatenating them together, like product 123, category 456, subcategory 789 gives part number 123-456-789 or some such.
I like to use natural identifiers as primary keys whenever practical. But "whenever practical" can be a serious constraint. If your natural identifier is derived by somehow combining three other fields, you have four choices:
Make the primary key be the combination of these three fields. This tends to be a pain. All your joins then must match on three fields, searches must test three fields, etc.
Create a new field that is the concatenation of the three fields, and use this as the priamry key. Then whenever one of the "basic" fields changes, also change this concatenated field. This is a very, very bad idea. Don't do it. It's redundant data, with all the bad things that come from redundant data.
Replace the three separate fields with one combined field. This is worse than #2. Now when you need the individual values, you have to take the field apart.
Give up and create a synthetic key, like a serial number. Use this as the primary key, and then just use the natural key for display purposes. If my natural key requires concatenating or otherwise manipulating three fields, I tend to go with this option.