I have two models, using Go 1.19:
type User struct {
Name string
ID int
}
type Order struct {
ID int
Name string
User *User
// or
UserID int
}
Of course, the database orders table has a foreign key to the users table via user_id.
Probably in different situations I have to use one of these models. When exactly?
Mb only user_id in DTO models, the user in responses from the server?
I will be glad for any information :)
It depends on your purpose. As usual, you have to use id when a table to include has meta info about your entity (often it's tables with a lot of rows and so heavy), therefore it will be better to use id, otherwise if it's table which describe some fields in initial table, you can use full entity.
Related
I have two tables
person
person_photos
with one-to-many relationship (i.e. each person can have list of photos)
e.g.
person {
person_id number, <<THIS IS PK>>
person_name varchar,
other_columns...
}
person_photos {
person_photo_id number,<<THIS IS PK>>
person_id number, <<THIS IS FK>>
photo blob
}
I want one of the photo marked as default. Is it ok to have reference to the default photo in master table
i.e.
person {
person_id number,<<THIS IS PK>>
person_name varchar,
other_columns...
default_person_photo_id number <<Reference to child table>>
}
This basically creates the circular reference between two table.
Is there any issue with this approach?
Or any other better way of doing it?
Note:
I can introduce one column in person_photo table to mark which one is default however I primarily introducing this default photo id in master table to avoid getting that information by joinin the photo table
I can also create a mapping table, but I would like go with that approach only if there is any issue circular design
Part of this depends on what RDBMS you are using. If you are using one without partial unique indexes (like MySQL for example) then then that is probably the best way you can do it.
On the other hand if you can have partial unique indexes then you can do as follows:
Remove person.default_person_photo_id
Add a boolean person_photos.is_default fild
CREATE UNIQUE INDEX default_person_photos_idx ON person_photos(person_id) WHERE is_default
Then you can never have more than one, and if you search for a photo based on a person_id where is_default then the index can be used, possibly saving you a join.
So in answer to your question without knowing your rdbms's capabilities, I can't say you there is a better way, and you certainly aren't doing anything wrong. But for some RDBMSs there is a better way.
I have the following situation with three tables, which are inherited from
contactBasics
contactSales (foreign key of contactBasics)
contactSupporters (foreign key of contactBasics)
The general data about a person is stored in contactBasics
Specific data about Sales People are additionally stored in contactSales
Specific data about Supporting People are additionally stored in contactSupporters
Is there a good way to handle e.g. contactBasics and contactSales as one object in code ?
help appreciated.
Endo
Assuming there is very similar data between contactSales and contactSupporters, you could just to have a 'contacts' table and add a contact_type field that clarifies which type of contact it is.
This also allows you to expand should you ever need another contact type.
You can use a short string field and have it be 'sales' or 'supporter', or you can go with an int field and have 1 = sales, 2 = supporter...etc. Which of those is up to your preference and app needs.
You can still keep both models if you want/need. In your associations, you can add conditions to differentiate between the two.
(or here for cake 3)
I have two class, User and Status, while a user will have a number of status, this is naturally Many-to-One relation and can be easily mapped to DB Tables.
However, the requirement also need User to maintain its “current” status, i.e., in the User Table, it need to have a foreign-key to the Status table. The result of this is having two foreign-keys between two tables in the opposite direction.
One obvious problem of this is once the records are inserted into the two tables, I can delete neither of them cause deleting from one table will violate the other table's foreign-key.
What is the best Design for this situation?
in your Status table , add a column that will determine whether this status record is "Current" or not.
** for performance issues , you can set only the "current" status records with '1' value and the rest with null value
you now don't have to use 2 foreign keys , only one - from Status to User.
if you are using hibernate as the post's tag :) you can create a view in the database that will select only the "Current" status records and will have the same structure as the Status table.
connect the view to the User entity using One-to-One relation,
I hope it helped you !
Do you have to keep the status in a separate table ? can it not be just represented by a java enum, and the User would have a status property. Something like this:
public enum UserStatus {
X, Y, Z;
}
public class User {
private UserStatus status;
...
}
Are tables with lots of columns indicative of bad design? For example say I have the following table that stores user information and user settings:
[Users table]
userId
name
address
somesetting1
...
somesetting50
As the site requires more settings the table gets larger. In my mind this table is normalized, all the settings are dependent on the userId.
I have a thing against tables with lots of columns it just seems wrong to me, but then I remembered that you can select what data to return from the table, so If the table is large I could still break it into several different objects in code. For example
[User object]
[UserSetting object]
and return only the data to fill those objects.
Is the above common practice, or are their other techniques that deal with tables with lots of columns that are more suitable to use?
I think you should use multiple tables like this:
[Users table]
userId
name
address
[Settings table]
settingId
userId
settingKey
settingValue
The tables are related by the userId column which you can use to retrieve the settings for the user you need to.
I would say that it is bad table design. If a user doesn't have an entry for 47 of those 50 settings then you will have a large number of NULL's in the table which isn't good practice and will also slow down performance (NULL's have to be handled in a special way).
Instead, have the following:
USER TABLE
Id,
FirstName
LastName
etc
SETTINGS
Id,
SettingName
USER SETTINGS
Id,
SettingId,
UserId,
SettingValue
You then have a many to many join, and eliminate NULL's
first, don't put spaces in table names! all the [braces] will be a real pain!
if you have 50 columns how meaningful will all that data be for each user? will there be lots of nulls? Most data may not even apply to any given user. Think 1 to 1 tables, where you break down the "settings" into logical groups:
Users: --main table where most values will be stored
userId
name
address
somesetting1 ---please note that I'm using "somesetting1", don't
... --- name the columns like this, use meaningful names!!
somesetting5
UserWidgets --all widget settings for the user
userId
somesetting6
....
somesetting12
UserAccounting --all accounting settings for the user
userId
somesetting13
....
somesetting23
--etc..
you only need to have a Users row for each user, and then a row in each table where that data applies to the given user. I f a user doesn't have any widget settings then no row for that user. You can LEFT join each table as necessary to get all the settings as needed. Usually you only need to work on a sub set of settings based on which part of the application that is running, which means you won't need to join in all of the tables, just the one or tow that you need at that time.
You could consider an attributes table. As long as your indexes are good, then you wouldn't have too much of a performance issue:
[AttributeDef]
AttributeDefId int (primary key)
GroupKey varchar(50)
ItemKey varchar(50)
...
[AttributeVal]
AttributeValId int (primary key)
AttributeDefId int (FK -> AttributeDef.AttributeDefId)
UserId int (probably FK to users table?)
Val varchar(255)
...
basically you're "pivoting" your table with many columns into 2 tables with less columns. You can write views and table functions around this structure to give you data for a group of related items or just a specific item, etc. You could also add other things to the attribute definition table to indicate required data elements, restrictions on the data elements, etc.
What's your thought on this type of design?
Use several tables with matching indexes to get the best SELECT speed. Use the indexes as a way to relate the information between tables using a JOIN.
I'm designing a DB and would like to know the best way to store this:
I have an user table and let's say it can have 100 item slots, and I store an ID.
Should I use JSON ({slot1:123232,slot20:123123123,slot82:23123}) or create 100+ fields (slot1, slot2, slotn)?
Thank you.
Third alternative, create another table for slots, and have a one-to-many relationship between users and slots. Your business logic would enforce the 100 slot limit.
I would recommend against doing the embedded JSON in the database. I'm not sure what DB you are using, but it will likely be very difficult to query the actual slot data for a given user without pulling out and parsing all 100 records.
To create a one-to-many relationship, you'll need a second table
Slots
id (primary key)
user_id (mapping to user table)
item_id (your slot # you want to store)
Now, you can do useful SQL queries like
SELECT * FROM Users,Slots WHERE Slots.user_id = Users.id AND Slots.item_id = 12345
Which would give you a list of all users who have slot item #12345
With database design normalization, you should not have multivalued attributes.
You might want this.
Users
=====
UserId
UserSlots
=========
UserId
SlotId
Value
Slots
=====
SlotId
Value
You should not create 100 fields.
Create a table with two fields, the ID and your "JSON Data", which you could store in a string or other field type depending on size.
You could normalize it as others have suggested, by that would increase your save and retrieve time.