MYSQL Database ID's - mysql

When someone registers on my site they get variables in 3 different tables.
However, due to unknown reasons, the ID's for some tables are more pushed up than others.
So someone will register and get these ID's
Table 1 - ID 12
Table 2 - ID 15
Table 3 - ID 13
I utilise these ID's being the same for various table joins, every user that signs up I have to manually go in and change the ID's!
I'm not sure what to do, it's really tedious. Should I just wipe the databases and restart?

It sounds like all three of your tables are set to auto-increment, and you are trying to imply a foreign-key relationship between them using their primary keys. This can work in the short-term, but if records are manually inserted, or if you have a scenario where not all three tables have data inserted, it will throw things off. You can reset the auto increment value to whatever you'd like, but this is only a temporary fix.
If this is the case, you should identify which of these is really the "master" table in relation to the others. Then ask yourself, is it really necessary to split this data into three tables, when in fact it all relates 1:1? And finally, if it is necessary to do so, then a best-practice you should consider would be to declare separate fields in the child tables and define these as having explicit foreign-key relationships to the master table.
I've only just registered so I can't comment, but it would be helpful if you could show the "create table" SQL statements.

If you know what you are doing and really want it to work this way. Then you can set the Auto Increment value to a specific number, like this ALTER TABLE Persons AUTO_INCREMENT=100.
If you don't really know what you are doing. You better read more about using databases, primary keys, relationship tables and more.

Related

How to design multiple child tables against a single parent table?

I'd be grateful if someone could advise me what the correct way is to approach this:
I have a parent table, with primary key master_id.
I have five child tables associated with the master_id, in a 1-to-n relationship, that record semantically different types of data (and wouldn't lend themselves to abstraction)
The only common fields in each child table are master-id (foreign key), created_by (user_id), created_time (timestamp).
The aim is to publish each child row associated with a master id in a chronological order on a webpage (imagine a forum posts style display), with the PHP building each "post" (i.e. row) slightly differently depending on the child table (and hence fields of data available to it).
Am I right in thinking there's no easy way to query this regardless of the table structure (and that ordering would be best done in PHP)? Is there any advantage to vertically partitioning out the 3 common fields into a single table combined with a table field?
This is a really difficult problem to solve, one I've worked on myself. Unfortunately, I don't have a good answer. You could use UNIONs and various types of JOINs, but you're going to potentially heavily kill your database's performance. Plus, you run into issues like, say you want the most 30 recent chronological entries. You'd have to query every child table for 30 entries (possibly 150 entries in all) and sort through them in your code since you don't know which child table(s) have the most recent 30 entries. 150 rows just to pull 30, blech.
Honestly, the best way I've found to implement such a thing is to have a table, possibly your master table, have columns dedicated specifically to what you want to show from your child table. For example, have columns in your master table that are something like, master_id, created_by, created_time, and notification_text (if you're trying to implement something like Facebook's timeline, for example). You could set up triggers on the child tables so that when you insert data into one of them, it automatically populates the data in the master table as well. Then when you're displaying the timeline, you just query the master table without bothering with the child tables at all.
Your schema would look something like:
Table master
- master_id
- created_by
- created_time
- notification_text
Table child1
- id
- master_id
- data1 (used to generate notification_text in master)
Table child2
- id
- master_id
- data21 (collectively used to generate notification_text in master)
- data22 (collectively used to generate notification_text in master)
- data23 (collectively used to generate notification_text in master)
...
What about you do a star model? It's commonly use to create datawarehouses however you could try to use something similar in your solution. If you are not familiar with the star model you can see more here.
Hope it helps.

Access VBA avoiding a conflict with primary key when adding a record to a linked table

So the root of this problem may lie in poor database design, some of the way this is set up is inherited from older versions. I just couldn't figure out a better way to do this.
I have four tables linked by the same field: [OBJECTID]. Each table is linked to an Access Form that controls the data. It is important that these tables be separate as the data is georeferenced and needs to be mapped separately, however they inherit several fields from one another by default.
Most of the time, the tables are in a one-to-one-to-one-to-one relationship, however occasionally, there is only data for the first table, and occasionally, there is only data for the second, third and fourth form.
Right now, the [OBJECTID] field in the first table is set to datatype autonumber, so that all subsequent linked records in the other tables can inherit that number. For the cases where the record in Tbl1 are not entered via Form1, it is easy enough to just assign a number that does not conflict with any current number, but how do I avoid assigning a number that could conflict with some future [OBJECTID] generated by the autonumber field in Tbl1?
Sorry if that is confusing! Thanks in advance for helping me think this through....
If the design is correct, there should be a relationship with referential integrity between tbl1 and table 2/3/4. Since you mention that occasionally, there is only data for the second, third and fourth form that means we have no referential integrity here :-/.
I would identify the fields that are common to all 4 tables, and create a "main" table with those, meaning that the main table MUST be filled. Then you create a 1 to 0,1 relationship to the other 4 tables, with an outer join, their PK beeing then a Long Integer.
For the source of your forms 1 to 4, use an outer join between MainTable and T1/2/3/4. The "subtables" will then inherit the PK of the main table.
Hope I am not too obscure.

Alternative to using same foreign key in almost every table

I am working with a database where "almost" every table in the database has the same field and same value. For example, almost all tables have a field called GroupId and there is only one group id in the database now.
Benefits
All data is related to that field and can be identified by said field
When a new group is created data will be properly identified for the group
Disadvantages
All tables have the this field
All stored procedures need to have this field as a parameter
All queries have to filtered by this field
Is this a big deal? Is there an alternative to this approach?
Thanks
If you need to be able to identify data by more than one group in the future, having foreign keys is a good practice. However, that deosn't mean all tables need to have this field, only the ones directly related to the group. For instance a lookuptable with state values may not need it, but the customers table might. Adding it to all tables willy-nilly can lead to bad things when you try to delete a record and have to check 579 tables (only 25 of which are pertinent). All this depends greatly on what the meaning of the groups is. Most of our tables have a relationship to the client table, because they contain data related to specific clients and because we don't want various clients to have the ability to see data for other clients. Tables which do not contain that kind of data do not.
Yes most queries may need the field and many stored procs will want to have it as an input variable, but if you truly need to filter on this information, then that is as it should be.
If however there is only one group and will never be more than one group, it is a waste of time, effort and space.

Will multiple table reduce the speed of the result?

I do have a datbase with multiple tables.
this multiple table is related to single name for example..
Table 1 contains name of the person, joined date,position,salary..etc
Table2 contains name of the person,current projects,finished,assigned...etc
Table 3 contains name of the person,time sheets,in,out,etc...
Table 4 contains name of the person,personal details,skill set,previous experiance,...etc
All table contains morethan 50000 names, and their details.
so my question is all tables contains information related to a name say Jose20856 this name is unique index of all 4 tables. when I search for Jose20856 all four table will give result and output to a front end software/html.
so do I need to keep multiple table or combined to a single table??
If so
CASE 1
Single table -> what are the advantages? will result will be faster? what about the system resource usage?
CASE 2
Multiple table ->what are the advantages? will result will be faster? what about the system resource usage?
As I am new to MySQL I would like to have your valuable opinion to move ahead
You can combine these into a single table but only if it makes sense. It's hard to tell if the relationships in your tables are one-to-one or one-to-many but seem to be one-to-many. e.g. A single employee from table 1 should be able to have multiple projects, skills, time sheets in the other tables. These are all one-to-many relationships.
So, keep the multiple table design. You also should consider using an integer-based primary key for the employee rather than the name. Use this pkey as the fkey in your other tables and you'll see performance improvement. (Also consider the amount of work you need to do if and when you want to change the name. You have to change all the names in all the tables. If you use a surrogate key, the int pkey, as suggested above, you only have to update a single row.)
Read on the web about database normalization.
E.g. http://en.wikipedia.org/wiki/Database_normalization
I think you can even add more tables to it. It all depends on the data and the relations.
Table1 = users incl. userdata
Table2 = Projects (if multiple users work on the same project)
Table3 = Linking user to projects (if multiple users work on the same project)
Table4 = Time spent? Contains the links to the user and to the project.
I think your table 4 can be merged into table 1 cause it also contains data specific to 1 user.
There is probably more you can do but as already stated it all depends and the relations.
What we're talking about here is vertical table partitioning (as opposed to horizontal table partitioning). It is a valid database design pattern, which can be useful in these cases:
There are too many columns to fit into one table. That's pretty obvious.
There are columns which are accessed relatively often, and some that are accessed relatively rarely. For example, if you very often need to display columns joined date,position,salary and columns personal details,skill set,previous experiance very rarely, then it makes sense to move these columns to separate a table, as it will (probably) improve performance in accessing those most commonly used. In MySQL this is especially true in case of TEXT and BLOB columns, since they're stored apart from the rest of the fileds, so accessing them takes more time.
There are NULLable columns, where majority of rows are NULL. Once again, if it's mostly null, moving it to a separate table will let you reduce size of your 'mani' table and improve performance. The new table should not allow null values and have entries only for rows where value is set. This way you reduce amount of storeage/memory resources as well.
MySQL specific - You might want tom move some of your columns from nnoDB table to MyISAM, so that you can use full text indexing, while still being able to use some of the features InnoDB provides. It's not a good design gnerally speaking though - it's better to use a full text search engine like Sphinx.
Last but not least. I'd suggest using a numeric field as a key joining all these tables, not a string.
Additional reading aboout MySQL partitioning (a bit outdated, since MySQL 5.5 added some new features)

MySQL updating 'categories' linking table

I have a table that holds bibliography entries, with a bibID primary key. I also have a table that holds a list of categories that can be assigned to the bibliography entries with a categoryID primary key. A table links these two tables as bibID:categoryID, so that each bibID can be associated with multiple categoryIDs.
Categories associated with bibliography entries can be edited via a form with checkboxes that represent all possible categories.
What is the most efficient way to update this relationship? I could just delete all relationships from the linking table associated with an entry and then reinsert whatever the form says, but this seems inefficient.
Efficiency is a slippery term. It can mean different things to different people.
However in most cases it means "performance", so I will assume that is what you mean for now.
I suspect the reality is that this is the most efficient (performant) way.
Other methods may appear more elegant, as they will preserve existing data, and only add missing data, but they will (potentially) require more database accesses and (definitely) more complicated SQL. One database call to delete and one to add should fix you up.
The only exception may be where there are large numbers of entries and the changes are small (or negligible). In this case you may need to reconsider.