My table contains a field 'priority'. Now I have following priorities to consider 'low', 'medium', 'high'.
What I am confused with is that:
Should I create a ENUM type field for priority values ?
Should I create a TINYINT type field and store values as 1, 2, 3 ?
Please note I would be required search and sort data based on this field.
Also, there will be indexing on this field.
You should use ENUM in case if you are sure none of the priority added in future because in that case you have to alter the table... BUt enum give surity of consistent data no other values gets inserted..
You should go with ENUM, as you said you have to search / sort, stroing them in tiny int would make you to additional processing like convert 1,2,3 back to 'low', 'medium', 'high'. while displaying.
Enum is ideal for such situvations
ENUM is a non-standard MySql extension. You should avoid it, especially if you can achieve the same results in a standard way. So its better to go with tinyint.
Related
Say I use the sql query:
select * from table t where t.name = "adam" and t.age > 10;
and in the column "age", there is more than just integer values. There are also values "old", "young", etc...
The result of this query would be all adam's with an age older than 10, but also all adam's with an age equal to one of the string values "old", "young", etc...
Why is this?
The reason for this behavior is MySQLs Type Conversion
which occurs implicit when you apply operators to data/columns of different types.
To the example you posted: It's generally considered bad practice to save data of different types/meanings in the same field.
I'd set the type of your 'age' column to 'int', and make it nullable. Then add another column named about_age which could be an ENUM with the values old and young. Whenever the 'age' column is NULL, your application can check the the about_age column. Only with this way, it's completely clear what your data means.
Sometimes I am not sure whether using enum or char(1) in MysQL. For instance, I store statuses of posts. Normally, I only need Active or Passive values in status field. I have two options:
// CHAR
status char(1);
// ENUM (but too limited)
status enum('A', 'P');
What about if I want to add one more status type (ie. Hidden) in the future? If I have small data, it won't be an issue. But if i have too large data, so editing ENUM type will be problem, i think.
So what's your advice if we also think about MySQL performance? Which way I would go?
Neither. You'd typically use tinyint with a lookup table
char(1) will be slightly slower because comparing uses collation
confusion: As you extend to more than A and P
using a letter limits you as you add more types. See last point.
every system I've seen has more then one client eg reporting. A and P have to resolved to Active and Passive for in each client code
extendibility: add one more type ("S" for "Suspended") you can one row to a lookup table or change a lot of code and constraints. And your client code too
maintenance: logic is in 3 places: database constraint, database code and client code. With a lookup and foreign key, it can be in one place
Enum is not portable
On the plus side of using a single letter or Enum
Note: there is a related DBA.SE MySQL question about Enums. The recommendation is to use a lookup table there too.
You can use
status enum('Active', 'Passive');
It will not save a string in the row, it will only save a number that is reference to enum member in the table structure, so the size is the same but its more readable than char(1) or your enum.
Editing enum is not a problem no matter how big your data is
I would use a binary SET field for this, but without labelling the options specifically within the database. All the "labelling" would be done within your code, but it does provide some very flexible options.
For example, you could create a SET containing eight "options" such as;
`column_name` SET('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') NOT NULL DEFAULT ''
Within your application, you can then define the 'a' as denoting "Active" or "Passive", the 'b' can denote "Hidden", and the rest can be left undefined until you need them.
You can then use all sorts of useful binary operations on the field for instance you could extract all those which are "Hidden" by running;
WHERE `column_name` & 'b'
And all those which are "Active" AND "Hidden" by running;
WHERE `column_name` & 'a' AND `column_name` & 'b'
You can even use the LIKE and FIND_IN_SET operators to do even more useful queries.
Read the MySQL documentation for further information;
http://dev.mysql.com/doc/refman/5.1/en/set.html
Hope it helps!
Dave
Hard to tell without knowing the semantics of your statuses, but to me "hidden" doesn't seem like an alternative to "active" or "passive", i.e. you might want to have both "active hidden" and "passive hidden"; this would degenerate with each new non-exclusive "status", it would be better to implement your schema with boolean flags: one for the active/passive distinction, and one for the hidden/visible distinction. Queries become more readable when your condition is "WHERE NOT hidden" or "WHERE active", instead of "WHERE status = 'A'".
For example, I have a column > shopping_cart.status; and this column status should for each record contain one of three values > "incomplete" "complete" or "shipped". My question is, should it be my application that makes sure that these are the only values used, or do i need to build this into the domain of this attribute on the database side?
Use enums thats exactly what they are meant for.
An ENUM is a string object with a value chosen from a list of
permitted values that are enumerated explicitly in the column
specification at table creation time.
An enumeration value must be a quoted string literal; it may not be an
expression, even one that evaluates to a string value. For example,
you can create a table with an ENUM column like this:
CREATE TABLE shoppingcards (
shoppingcardstatus ENUM('incomplete', 'complete', 'shipped')
);
see: http://dev.mysql.com/doc/refman/5.0/en/enum.html
I would like to store a user status in the database, so, I will use a char to store the status, for example, "active", "inactive", "close". I will use "a", "i", "c" to represent these status. But it is non-sense to store a varchar in database? should I use a char type or set?
**the database in mysql.
You may want to consider using an int or an enum instead. If you do want a char type, CHAR(1) NOT NULL should be fine. With an enum, it would be:
status ENUM('active', 'inactive', 'close')
With an int:
status tinyint
Using an int is a good option, but document the values well.
One thing to beware of is that adding a new value to an enum requires rewriting the entire table. I generally recommend storing CHAR or VARCHAR. One can add a FK reference to a table of legal values if you want an other aspect of enums, that of requiring the value to be a listed one. Then the 'almost enum' can be extended by adding another value to the FK'ed table.
I need to create a good/neutral/bad field. which one would be the more understandable/correct way.
A binary field with null (1=good, null=neutral, 0=bad)
An int (1=good, 2=neutral, 3=bad)
An enum (good, neutral, bad)
Any other
It's only and informative field and I will not need to search by this.
NULL values should be reserved for either:
unknown values; or
not-applicable values;
neither of which is the case here.
I would simply store a CHAR value myself, one of the set {'G','N','B'}. That's probably the easiest solution and takes up little space while still providing mnemonic value (easily converting 'G' to 'Good' for example).
If you're less concerned about space, then you could even store them as varchar(7) or equivalent and store the actual values {'Good','Neutral','Bad'} so that no translation at all would be needed in your select statements (assuming those are the actual values you will be printing).
In Mysql you ought to be using an enum type. You can pick any names you like without worrying about space, because Mysql stores the data as a short integer. See 10.4.4. The ENUM Type in the documentation.