Using a table to provide enum values in MySQL? - sql

Is there a way to map one of the the columns contents of a MySQL table to an enum on another table in MySQL? I thought this would be a no brainer, but there doesn't seem to be any info that I can find on the subject.
Any advice or help on this matter would be cool and if it's not possible, does anyone know of an internal reason why it wouldn't be possible?
Best regards everyone :)
Gary

The enum type is handy as a one-off, but it doesn't scale well to multiple tables and isn't standard SQL either.
Best thing to do here is to use normal tables and relations:
Define a new table to hold the list of possible values; let's call it Master1
In the other two tables (let's call them Table1 and Table2), don't make the field an enum; just make it a normal field with a foreign key relation to Master1.
The foreign key relation will do the job of restricting to a list of possible values; and because foreign keys and relations are absolutely standard SQL, this approach will have other benefits - for example reporting tools can recognise the foreign key and understand how to use the related data.

If it doesn't do it, don't do it
Surely you just want a table of possible keys and then a foreign key mapping to that.
If you want a table with possible enum values and restrictions, go for groupings via another table or a groupid in the same table (if group members are unique).
Smells like table-stink though JOIN wise. Maybe best doing this in a stored procedure or in the app code and mapping it to a native value?

Related

is it necessary to have foreign key for simple tables

have a table called RoundTable
It has the following columns
RoundName
RoundDescription
RoundType
RoundLogo
Now the RoundType will be having values like "Team", "Individual", "Quiz"
is it necessary to have a one more table called "RoundTypes" with columns
TypeID
RoundType
and remove the RoundType from the rounds table and have a column "TypeID" which has a foreign key to this RoundType table?
Some say that if you have the RoundType in same table it is like hard-coding as there will be lot of round types in future.
is it like if there are going to be only 2-3 round types, i need not have foreign key??
Is it necessary? Obviously not. SQL works fine either way. In a properly defined database, you would do one of two things for RoundType:
Have a lookup table
Have a constraint that checks that values are within an agreed upon set (and I would put enums into this category)
If you have a lookup table, I would advocate having an auto-incremented id (called RoundTypeId) for it. Remember, that in a larger database, such a table would often have more than two columns:
CreatedAt -- when it was created
CreatedBy -- who created it
CreatedOn -- where it was created (important for distributed systems)
Long name
In a more advanced system, you might also need to internationalize the system -- that is, make it work for multiple languages. Then you would be looking up the actual string value in other tables.
is it like if there are going to be only 2-3 round types, i need not
have foreign key??
Usually it's just the opposite: If you have a different value for most of the records (like in a "lastName" column) you won't use a lookup table.
If, however, you know that you will have a limited set of allowed/possible values, a lookup table referenced via a foreign key is probably the better solution.
Maybe read up on "database normalization", starting perhaps # Wikipedia.
Actually you need to have separate table if you have following association between entities,
One to many
Many to many
because of virtue of these association simple DBMS becomes **R**DBMS ( Relation .)
Now ask simple question,
Whether my single record in round table have multiple roundTypes?
If so.. Make a new table and have foreign key in ROUNDTable.
Otherwise no.
yeah I think you should normalize it. Because if you will not do so then definitely you have to enter the round types (value) again and again for each record which is not good practice at all in case if you have large data. so i will suggest you to make another table
however later on you can make a view to get the desired result as fallow
create view vw_anyname
as
select RoundName, RoundDescription , RoundLogo, RoundType from roundtable join tblroundtype
on roundtable.TypeID = tblroundtype .typeid
select * from vw_anyname

Table referenced by other tables having different PKs

I would like to create a table called "NOTES". I was thinking this table would contain a "table_name" VARCHAR(100) which indicates what table put in the note, a "key" or multiple "key" columns representing the primary key values of the table that this note applies to and a "note" field VARCHAR(MAX). When other tables use this table they would supply THEIR primary key(s) and their "table_name" and get all the notes associated with the primary key(s) they supplied. The problem is that other tables might have 1, 2 or more PKs so I am looking for ideas on how I can design this...
What you're suggesting sounds a little convoluted to me. I would suggest something like this.
Notes
------
Id - PK
NoteTypeId - FK to NoteTypes.Id
NoteContent
NoteTypes
----------
Id - PK
Description - This could replace the "table_name" column you suggested
SomeOtherTable
--------------
Id - PK
...
Other Columns
...
NoteId - FK to Notes.Id
This would allow you to keep your data better normalized, but still get the relationships between data that you want. Note that this assumes a 1:1 relationship between rows in your other tables and Notes. If that relationship will be many to one, you'll need a cross table.
Have a look at this thread about database normalization
What is Normalisation (or Normalization)?
Additionally, you can check this resource to learn more about foreign keys
http://www.w3schools.com/sql/sql_foreignkey.asp
Instead of putting the other table name's and primary key's in this table, have the primary key of the NOTES table be NoteId. Create an FK in each other table that will make a note, and store the corresponding NoteId's in the other tables. Then you can simply join on NoteId from all of these other tables to the NOTES table.
As I understand your problem, you're attempting to "abstract" the auditing of multiple tables in a way that you might abstract a class in OOP.
While it's a great OOP design principle, it falls flat in databases for multiple reasons. Perhaps the largest single reason is that if you cannot envision it, neither will someone (even you) looking at it later have an easy time reassembling the data. Smaller that that though, is that while you tend to think of a table as a container and thus similar to an object, in reality they are implemented instances of this hypothetical container you are trying to put together and operate better if you treat them as such. By creating an audit table specific to a table or a subset of tables that share structural similarity and data similarity, you increase the performance of your database and you won't run in to strange trigger or select related issues later.
And you can't envision it not because you're not good at what you're doing, but rather, the structure is not conducive to database logging.
Instead, I would recommend that you create separate logging tables that manage the auditing of each table you want to audit or log. In fact, some fast google searches show many scripts already written to do much of this tasking for you: Example of one such search
You should create these individual tables and then if you want to be able to report on multiple table or even all tables at once, you can create a stored procedure (if you want to make queries based on criterion) or a view with an included SELECT statement that JOINs and/or UNIONs the tables you are interested in - in a fashion that makes sense to the report type. You'll still have to write new objects in to the view, but even with your original table design, you'd have to account for that.

Are relationship tables really needed?

Relationship tables mostly contain two columns: IDTABLE1, and IDTABLE2.
Only thing that seems to change between relationship tables is the names of those two columns, and table name.
Would it be better if we create one table Relationships and in this table we place 3 columns:
TABLE_NAME, IDTABLE1, IDTABLE2, and then use this table for all relationships?
Is this a good/acceptable solution in web/desktop application development? What would be downside of this?
Note:
Thank you all for feedback. I appreciate it.
But, I think you are taking it a bit too far... Every solution works until one point.
As data storage simple text file is good till certain point, than excel is better, than MS Access, than SQL Server, than...
To be honest, I haven't seen any argument that states why this solution is bad for small projects (with DB size of few GB).
It would be a monster of a table; it would also be cumbersome. Performance-wise, such a table would not be a great idea. Also, foreign keys are impossible to add to such a table. I really can't see a lot of advantages to such a solution.
Bad idea.
How would you enforce the foreign keys if IDTABLE1 could contain ids from any table at all?
To achieve acceptable performance on joins without a load of unnecessary IO to bring in completely unrelated rows you would need a composite index with leading column TABLE_NAME that basically ends up partitioning the table into sections anyway.
Obviously even with this pseudo partitioning going on you would still be wasting a lot of space in the table/indexes just repeating the table name for each row.
Isn't it a big IF that you're only going to store the 2 ID fields? If I have a StudentCourse (or better yet Enrollment) table that has StudentID & CourseID, but wouldn't EnrollmentDate go in this table as well since not all students enroll on the first day of class. Seems like a bad idea to add this column to an already bloated table where most records will be null.
The benefit of a single table could be a requirement that the application has the ability to allow user/admin to create these relationships with data (Similar to have a single lookup or reference list table) and avoid having to create a new table to address these User Created References. Needing dynamic querying may benefit as well. An application that requires such dynamic data structure requirements might be better suited for a schemaless or nosql database.

What is the best way to tie 1 table to many tables

I have a table. Call it TableA
this table will link to many tables and ideally be enforced by database relationships in (many-1)(TableA-TableB)
(many-1)(TableA-TableC) ... etc
The solution i have is to put all the foreign keys of TableB, TableC, etc in TableA along with a "Type" field (which contains a word version of which relationship is to be enforced). however i think there must be a better way.
What would you do?
I'd appreciate any advice in this and thanks.
This is a perfectly acceptable approach - foreign keys are indeed the correct way of modeling a many-to-one relationship.
Generally, you can't just say you want to make a solution "better"; rather, you should have a specific goal in mind. Faster, shorter implementation, less memory, whatever. Even better is if you have a specific use case you would like to optimize for.
Edit: your question is more clear now that you've edited it. If I understand correctly, you feel your current implementation is inefficient because one of your TableA items can be attached to at most one other item, be it from TableC, TableC, etc.
If that is correct, what I might do is implement the foreign key in Table A as both an ID and a table name, rather than having a new column for each new type of object you want to add to your system. Of course, this would prevent you from changing table names, so a more robust solution would be to have another table mapping unique ids to object types (stored as table names). Then the foreign key in Table A would be item_id and object_type_id, and you could retrieve the object by looking up object_type_id in the object_types table to get the table name.
If you want to add referential integrity enforced by the database server, each key must be represented by a unique column in TableA.
It's hard to give more advice than that without knowing more about what your design is attempting to do.

DB table refactoring

Hi I'm using ms2005 for a simple calendaring system.
We have three 'legacy' tables: Groups, Units and Staff.
I need to give each record in the tables a unique identifier (carrying across all 3 tables).
What would be best way to approach this? I am using NHibernate and was was wondering whether that could do it for me.
Anyway, any nods in the right direction much appreciated.
The usual practice is to create a surrogate primary key on each table using an int with IDENTITY(1,1).
If you need a unique values across systems then use a UNIQUEIDENTIFIER column (GUID).
Are you saying that the same identifier shouldn't appear in more than one table? That would be a fishy assertion that would suggest that more discussion is needed.
It would be a "Bad Smell", in a refactoring sense.