Just wanted to ask.
I have site where each user is linked to an ID in the Database and this Primary Key is included in many tables. The fastest way for me to pull a users information is to have this ID.
Would it be considered bad practice to put this ID in website HTML code? eg id="theIDnumber"
Otherwise i can just use the username and then reference this in the Database for this ID - which is fine but using the ID would be faster I believe.
thoughts?
I'd say no, if your keys are predictable. A trivial example: if you are using sequentially incrementing primary keys users can extract information from data that could be a privacy concern. e.g. they can infer which account was created before their account. Life also becomes easy for those trying to systematically leech information from your site.
Some related reading
https://stackoverflow.com/a/7452072/781695
You give your end users the opportunity to mess with those variables
and pass any data that they like. The counter measure to mitigate this
vulnerability is to create indirect object references instead. This
may sound like a big change, but it does not necessarily have to be.
You don't have to go and rekey all your tables or anything, you can do
it just by being clever with your data through the use of an indirect
reference map.
https://security.stackexchange.com/a/33524/37949
Hiding database keys isn't exactly required, but it does make life
more difficult if an attacker is trying to reference internal IDs in
an attack. Direct references to file names and other such internal
identifiers can allow attackers to map the internal structure of the
server, which might be useful in other attacks. This also invites path
injection and directory traversal problems.
https://www.owasp.org/index.php/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet
An object reference map is first populated with a list of authorized
values which are temporarily stored in the session. When the user
requests a field (ex: color=654321), the application does a lookup in
this map from the session to determine the appropriate column name. If
the value does not exist in this limited map, the user is not
authorized. Reference maps should not be global (i.e. include every
possible value), they are temporary maps/dictionaries that are only
ever populated with authorized values.
Related
To start off, we have the following scenario (not exactly like this but for confidential reason I will not take the risk to explicitly describe the project) where let's say A person can Have Many home addresses and obviously an address belong to at most one person. This is pretty much a one to many relationship where there are 2 tables (Person and Addresses) with the second one holding a FK referencing the owner. But sadly i was told that my system should also allow users to enter Addresses first, so a FK that does not exist in the Person table yet. I came to the conclusion that i just have to drop that constraint. Do you thing it's a common thing to do? Furthermore I thought to maintain consistency even without FK (declared explicitly), if someone update the Person ID, since i dont want the user to do it in both table, is it possible to create a Trigger (I'm using Mysql server) that will update the second table automatically (if that person has an address)? If yes, any hint to how to write that (I'm not familiar with triggers)
You can maintain the 1:N relationship by creating the kind of intermediate table normally associated with M:N relationships but adding a uniqueness constraint on the address referencing field; alternatively, you can just make address' reference to person nullable, making it an optional reference.
[Edit]
Scripts from MySQL dump wrap their contents with something like:
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=0;
....
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
As you can probably guess, it temporarily turns off foreign key checks to allow inserting interdependent data out of order. However, you should be sure of the trustworthiness of the import data as I believe it does not recheck the data when turned back on (so it can allow data that violates FK constraints to persist).
If you need the ability to add "address" before "person" with user entered data, then you are back the original situation of needing optional keys or another table; or just not actually saving the "address" info (but instead holding it locally in the data entry program) until after the "person" info is sufficient/complete.
having a bit of trouble finding the correct way to model per user data in couchbase and sync up via couchbase mobile for user specific data. In couchdb you have a separate database per user. What is the best approach in couchbase ?
In Couchbase there is no such thing as "user data". Its generic and open for your designs.
Normally when you design your object domain model for Couchbase you would inject metadata in your key structure.
For example:
Key for Account: "Acc#123456789" - where prefix "Acc#" is telling about type of the key, and "123456789" adds particular address instance of this key...resulting in the unique key.
Similarly if you want to encode associated address to the account, you'd architect the following key: "Acc#123456789#Addr" - where postfix "#Addr" identifies type of the key for address object
Now, if you want to have user specific keys, you just simply inject user identifier into the key value (from the example above):
key "Acc#123456789" will transform to "usr#12345#Acc#123456789"
key "Acc#123456789#Addr" will transform to "usr#12345#Acc#123456789#Addr"
Read more on Couchbase data modeling here and keys and metadata
You can create your documents in that way which can able to ease the retrieve all related entity. e.g.
Create your documents with user_{Guid} consider Guid as your UserID
Make all other related document with this same Guid like credential_{Guid} so when user logged in we can have userID in session and get all information of that user.
I'm working on a product that sends periodic emails to the registered customers, and I would like to implement some kind of an unsubscription mechanism from these emails.
There are about 5 types of emails and a User MySql table that contains all the users. New users are subscribed to all the email types by default, and can unsubscribe from each email type separately.
My question is how should I store these unsubscriptions to the DB, while keeping high performance and scalability and without over-complicating things. Here are a few options that came up, each has its own advantages and disadvantages:
Adding a boolean column on the User table for every report type with a default value of true.
Creating a new Unsubscription table with one-to-one relationship to the User table. Every email type will get a column and every user get a row.
Creating a new Unsubscription table with many-to-one relationship to the User table. Every unsubscription request will create a new row on the table.
Is there a best practice for storing unsubscription information? What are the database-design issues?
option 3. is the most 'normalised' in terms of db schema and means email types can be added without having to do any migrations on the db... it's also the most natural option if you already have a table for storing email types
however you will get better performance with option 1. (no JOINs) at the expense of needing to do a db migration if you add a new email type
option 2. seems to have the inflexibility of 1. while still needing a separate table so would be my least favoured option
A couple of other options to consider:
instead of several boolean fields on the model (option 1.) use a single BitField https://github.com/disqus/django-bitfield to represent unsubscriptions... this has the advantage that you can add new email types without migrating, plus querying is just as fast. removing types you'd have to be careful though
as mentioned above, if you have a table for EmailType already it makes sense to have a many-to-many relation on the User model. But you could use django-denorm to automatically update a BitField on the model which might give the best of both worlds
I am designing a database for MySQL to create a relationship between two users of an application. I am unsure of the best way to store the particulars of this relationship, though I currently intend to use one record per relationship in a link table called RELATIONS. Each user has basic data like their name and occupation stored in the USERS table, and more specific personal data stored linked by FKs in other tables, which we'll say are called OTHER1, OTHER2, and OTHER3, which will all contain some other data to be shared, we'll say each in a field called [Data] and identified with ID and USER_ID.
The difficulty is that the application allows users to specify what basic and advanced data that they show to each user, and vice versa. The RELATIONS link table needs to have FKs to USERS for the two users to set up the relationship, but I don't know how best to specify what data each user is able to share, because virtually all of the data that the database stores is stored optionally but all needs to possibly be hidden from a user that doesn't have permission to view it. The second user should be able to see if there is data there, however, so that he might request permission to view it.
My model for RELATIONS at this point looks like this:
RELATIONS
ID
USER_ID1
USER_ID2
USER1OTHER1_ID [(Value), Unshared, Null]
...
USER1OTHER100_ID [(Value), Unshared, Null]
USER2OTHER1_ID [(Value), Unshared, Null]
...
USER2OTHER100_ID [(Value), Unshared, Null]
So USER1OTHER1_ID will contain the FK to OTHER1 if User1 has shared it with User2, will be "Unshared" if it's present but unshared, and Null if User1 has no data in OTHER1. Same for USER2OTHER1 for sharing with User1. I don't like having a massive field array, though, and I don't like how I'd have to update all the relations if User1 later decides to add data to OTHER1. Is there a simpler and more normalised way of representing this?
I believe the normalized approach would be to only store whether userA has permissions to view the userB's data and not add FK references to it in the Relations table because you already have references to userB's data somewhere else. By storing additional references in the Relations table you are duplicating data and will have to ensure that it stays synchronized as you described in your question which will probably be an ongoing maintenance hassle and one more thing you have to keep in mind whenever you refactor your code.
If you only store permissions (no fks) in the Relations table you would join on a table (User?) to get the User's shared data or to see if it exists depending on the permission.
As far as having an excessive number of columns on the relations table, I don't think you will have enough to see a real degradation when querying the table (you could correct me on this). For clarity sake in the db code as well as your application code, I think you are better off to have a column for each permission than to try to find a short cut such as combining them in a clob or something.
The most succinct way I can readily imagine is to store one INT with the relationship, which is a bit-wise representation of the permissions; with the interpretation of that INT in the code. The INT will need as many bits as you have unique permissions, and then define constants for each of them. I'm not sure what language you are implementing in, but there about a few ways to skin this cat...
So, some pseudo-code might look like this:
define RELATION_PERMISSION_SEE_MY_PHOTOS = 1;
define RELATION_PERMISSION_SEE_MY_FRIENDS = 1<<1;
define RELATION_PERMISSION_SEE_MY_EMAIL = 1<<2;
and then build some arrays of supporting info (like localized strings, etc) to build your interface with, and then do something like this to modify it:
int new_permission = 0
foreach(user-selected-permissions as selected_permission) {
new_permission |= selected_permission
}
my_relation_model.permissions_flags = new_permission
one way would be to use essentially key value pairs..
similar to this:
user_1_id
user_2_id
field
privilege
.. because virtually all of the data that the database stores is stored optionally ...
Considering this, I would suggest 6NF for all user attributes.
The User table serves as an anchor and ideally holds only UserID.
Each user attribute has its own table with only UserID and the attribute value (6NF); a row exists only if the attribute is specified (all attribute values are NOT NULL).
Each attribute has also a sharing table with only OwnerID, VisitorID. A row exists only if the owner shares the attribute with the visitor.
In this model, a user can share only attributes that do exists. If you want to allow sharing of not specified attributes, point the OwnerID to the User table too.
To make thing simpler you can (should) create a view(s) for user data.
I'm designing a database where two fields have a many-to-one relationship, but I also need a one-to-one relationship between them, and I would like some advice on whether there is a better way to do it than what I've got right now.
My tables are accounts and users. An account can have multiple users, but each account can only and must have one owner. A user can be related to only one account.
I have an account field in the users table, which stores the ID of the account the user is related to. In the accounts table, I have an owner field, which stores the ID of the user who owns the account (i.e. the head admin).
I'm using InnoDB so I can make use of foreign keys. The problem is that I can't create an account or a user without the other being created first (due to the restraints of the foreign keys), so I made owner nullable. Now I can create an account with a null owner, then create the user, and finally set the owner on the account to the user.
Is this acceptable, and is there a better way?
Here are some possible other ways I've come up with, and my thoughts on each:
Have a boolean owner field in the users table. Since every account can only have one owner, this way seems less than ideal because I'd have to ensure only one user per account has the attribute set to true.
Have a third table called owners. This seems like more overhead and more work for no good reason since it's effectively the same as having an owner field in the users table.
How I have it now makes the most sense to me, but it's a little awkward having to set a null owner until I create the user, and then coming back to set it after the fact.
I'd appreciate any input you can give me. Thanks!
This question is similar, but there's no mention of foreign keys: Designing Tables: One to many and one to one at same time?
In general is a bad idea if your schema cannot be sorted topologically, i.e. if you cannot establish an ordering where a table only refers to tables preceding it in the ordering. This sort of "layered" dependency is also a very nice property to have for example for software modules (you have a problem if two modules depends on each other).
In your case you have user that refers to account and account that refers to user so clearly there's no way to find a topological ordering.
One standard solution in this case is to introduce a separate table e.g. "role" where you have three columns: user, account and role. The column role can be either "owner" or "guest".
The fact that you know that (given the current requests) an account must have one and only one owner, or that a user must be listed in one and only one account are not IMO rules that are really pertinent to the domain of "users" and "accounts".
You can implement those rules easily, but structuring your data so that you have no other possibility is IMO a mistake. You should aim to model the domain, not the specific rules... because people will change their mind about what those rules are.
Can you conceive a user with two accounts? Can you conceive an account with multiple owners/admins? I can... and this means that most probably quite soon this will be a request. Structuring the data so that you cannot represent this is looking for troubles.
Also when you have cyclical dependencies in the model your queries will be harder to write.
A very common case is for example to try to represent a hierarchical part list database using just one table with a "parent" field that points to the table itself... much better is having two tables instead, part and component, where component has two references to part and and a quantity.
Your solution is fine.
If you're uncomfortable with the owner column being nullable, you could rely on some magic user record (perhaps with an id of zero) which would be the "system user". So newly created accounts would be owned by user-zero, until their ownership was suitably redefined. That seems smellier than allowing accounts to have a null owner, to me, anyway.
For the current requirement to have only one account per user
alter table UserAccount add constraint un_user_account unique(UserID);
and when the requirement changes to many-to-many, drop the constraint
alter table UserAccount drop constraint un_user_account;
For the one owner only, simply enforce that on the application level.