Database which each user sees differently - 'multiuser'/'multiview' database? - database

Is there an existing implementation or even a name for a type of database which allows multiple points of view? What I mean is for instance if one user changes an article's title then the change will only be visible to that particular user and everyone else will see the original title. If several users change it to the same new title then the new title becomes the 'master view', or the 'unfiltered view' of the database, initiated either by the database or from the application.
I'm coding in C# and am familiar with SQL and starting with MongoDB but the question is about the concept and whether abstractions, implementations, or design patterns of it exist.

If your "point of views" are completely separated, you could just use a new database for each user.
From your question it seems you want to have some degree of interconnectedness. Perhaps articles created by any user should be visible to everyone? Is it only changes after creation that should be private? How about updates from the original author?
I think you just need to specify the behavior you need, and design a database that can handle that.
One solution could be to use both the (article) id and the user id as the key for your tables. That way you can completely replace content for specific users. Let's say you want to find article 123, as seen by user 456, or if that user doesn't haven't edited it, as seen by user 789, or if that user haven't edited it, just pick any version:
SELECT * FROM articles WHERE id = 123 ORDER BY user_id = 456 DESC, user_id = 789 DESC LIMIT 1

Related

NoSql - entity holds an owner ID field vs owner holds list of child ID's

I am currently exploring MongoDB.
I built a notes web app and for now the DB has 2 collections: notes and users.
The user can create, read and update his notes.
I want to create a page called /my-notes that will display all the notes that belong to the connected user.
My question is:
Should the notes model has an ownerId field or the opposite - the user model will have a field of noteIds of type list.
Points I found relevant for the decision making:
noteIds approach:
There is no need to query the notes that hold the desired ownerId (say we have a lot of notes then we will need indexes and search accross the whole notes collection). We just need to find the user by user ID and then get all the notes by their IDs.
In this case there are 2 calls to DB.
The data is ordered by the order of insertion to the notesIds field in the document.
ownerId approach:
We do need to find the notes by their ownerId field across the notes collection which might be more computer "intensive".
We can paginate / sort the data as we want - more control over the data.
Are there any more points you can think of?
As I can conclude this is a question of whether you want less computer intensive DB calls vs more control over the data.
What are the "best practices"?
Thanks,
A similar use case is explained in the documentation. If there is no limit on number of notes a user can have, it might be better to store a userId reference field in notes document.
As you've figured out already, pagination would be easier in the second approach. Also when updating notes, you can simply updateOne({ _id: "note_id", userId: 1 }) instead of checking user's document if the note actually belong to the user.

is there a way to have 2 dates under a customer's name in Microsoft access

I'm an intern student at a company that does both wiring and aircon services. The job that they gave me was to make a database for them. I don't have any experience in anything related to databases.
So, I started to look up videos and stuff to at least learn a bit about databases and made something that works and I made it after 1.5 months of learning.
in the database that I created,
I have 1 table (CustomerDetailsT):
CustomerID (pk)
CustomerName
PhoneNumber
Address
Aircond (type and model of ac,ex: WM daikin 1.0HP)
AcDetails (what has been done for the ac.)
Others (yes/no) (Wiring, installing a fan and so on)
WhatHasBeenDone (shows what has been done for others)
Then 3 queries (CustomerOthersDetailsQ, CustomerAcDetailsQ, CustomerDetailsQ).CustomerAcDetailsQ has CustomerName, PhoneNumber, Address, Aircond and AcDetails. CustomerOthersDetailsQ has CustomerName, PhoneNumber, Address, Others, and WhatHasBeenDone.CustomerDetailsQ has CustomerID, CustomerName, PhoneNumber and Address
And 1 form with 3 subforms.
it's a search form, which would search for customers as we're typing in their name/phone number and it will show what has been done for the customer.
With this, I have created what the company wants, but now they want to add dates. Dates which would show when we have done something for a customer. Dates for Aircond and the Others stuff.
I've tried with what I know and it didn't work. tried searching it on youtube and google, but still couldn't find it.
how can I go about doing this?. I have tried having separate tables for each service, but it became a hassle when I wanted to create a new customer. . I hope I could some help, I could send pictures if someone needs them.
[1]: https://i.stack.imgur.com/mtrmC.png [The Customer search form] [1]: https://i.stack.imgur.com/A3Y9d.png [example of a customer that has ac installation] [1]: https://i.stack.imgur.com/dsGL5.png [example of a customer that has both ac and wiring done]
Acknowledging the question is too broad, here is some guidance. One of the nice things about Access is that each database is a single file. First protect your work by finding that file and make two copies. Make a backup and a play around version. Only mess with the play around version.
Your question indicates you are still learning Table Normalization and 1 to many relationships. Both of these topics are general to all databases, so you don't have to restrict yourself to just Access when looking for guides and Youtube videos.
Part of normalization is putting separate entities into their own tables. Also, in Access there is a big payoff for using the Relationship Tool, so here is a rather lame example of normalization:
Make sure to select the checkboxes when setting up relationships.
WhatHasbeenDone should also have WhatHasbeenDoneDate. I've wrapped AC and Other as Unit because later it will be easier than having two WhatHasBeenDone tables(AC)(Other).
Now imagine someone taking the customer request call. They just want to see a form to enter the customer details, request, unit-type, etc. They don't want to see those tables. Even with training entering data in the tables is error prone. The person fulfilling the request just wants to enter what they did and when. That's how you start to figure out what your final Data entry forms will look like.
Since we normalized the tables and used the relationships tool, the payoff is Access can give us an assortment of working starter forms. Select Each Table and then hit Create and then hit Form. Choose your Favorites and start playing around from there. While playing, keep in mind that Access will not let you add an item on the many side of a relationship unless there is an item on the 1 side.
For example I selected the customers table and hit create form:
Access uses a concept of form and subform based on separate but related tables. So, to get a form that shows what has been done for each customer I created a form for the What has been done table, and dragged it onto the customers form:
Unless an ID is also being used as a part number or something there is probably no reason for the person entering data to see it. So I removed the texboxes bound to ID's. Except for UnitTypeID, where I replaced the textbox with a combobox that displays the userfriendly UnitDescription. The ID's are still part of the form recordsources, Access is still adding new IDs and using those IDs to put the appropriate data in the right tables.
Oh, didn't we need dates (went back and added a date to the table, and adjusted the subform accordingly). Also changed the subform format from single record to continuous records to show multiple dates:
In conclusion and in my opinion your final forms will use VBA behind the scenes to insert data from the forms into the tables. This is because either you will want to rapidly insert multiple records or How the end users think about the data will not match the default forms and subforms approach Access depends upon to figure out how to insert the data. However, the default approach is fast and I always use it for version 1 of my Access Databases.
P.S. For simplicity I avoided including any Many to Many relationships

Best way to store comments with mentions (#FirstName) in database

Was wondering what is the best way to store comments in a database (sql) that allows mentioning of other users by a non-unique natural name?
E.g. This is a comment for #John.
The client application would also need to detect and link to corresponding user profile if his/her name was clicked.
My initial thought was to replace the user's first name with the id and some metadata and store that in the DB: This is a comment for <John_51/> where 51 is the id of that user. Clients can then parse that and display the appropriate user name and profile links.
Is this a good approach?
Some background:
What I would like to achieve is similar to facebook posts where it allows you to 'tag' a user by just mentioning their name (not the unique username) in a post. It doesn't have to be as complex as facebook as what I need it for isn't for a post, but just comments (which can only be text, as opposed to posts which could be text mixed with videos/images/etc).
The solution would affect the database side (how the comments are stored) and also the client side (how the comments are parsed and displayed to the user). The clients are mobile apps for iOS and Android but also looking to expand to a web application as well.
I don't think the language matters as much but for completeness sake, I'm using Python's Flask with SQLAlchemy frameworks on the backend.
Current DB schema for comments
COMMENT TABLE:
id (<PK>)
post_id (id of the post that the comment is for: <FK on a post object>)
author_id (id of the creator of the comment: <FK on a user object>)
text (comment text: <String>)
timestamp (comment date: <Date>)
Edit:
I ended up going with metadata in the comment. E.g.
Hey <mention userid="785" tagname="JohnnyBravo"/>!
I included the user's name (tagname) as well so that client application can extract the name directly from the comment text instead of adding another step to look up who user 785 is.
The big problem here is if the username is not a stable reference, you need to abstract it to an id reference, while still keeping the the text reconstructable, but the references queryable.
Embedded collections and dynamic typing are a great option if you're using a NoSQL database. It would be fairly straightforward.
{
_id: ...,
text: [
"Wow ",
51,
", your selfie looks really great, even better than ",
72,
"'s does."
],
...
}
That way you could query references, while still easily reconstructing the content. BUT since you're using SQLAlchemy, that's a no go. Your methodology seems fine, but because your doing magic in the string you'll need to escape your delimiters, (as well as escape the escape character) if they exist in the text. Personally, I would use # as the delimiter since it's already a special character. You'd also need to identify the end of the id, in case the user sticks a bunch of numbers after the #mention, so
Wow #51#, your selfie looks really great, even better than #72#'s does. email me! john\#foo.com. Division time!!! with backslashes! 12\\4 = 3
IF querying posts for references is also important to you. You'll also need to maintain a separate POST__USER junction table that stores a row for the post and for each user id, so that when you load an object into memory, you can construct a collection. You could decide to add the junction table later, but it would be a fairly expensive migration.
If #name is not unique,you have to somehow associate the non-unique name, via the session, with the unique owner of the natural name, and do this ideally before storing it in the database. Storing a non-unique name in the database, if it cannot be resolved to its unique owner, is not of much value.
Since you mention "sql" I assume you're using a relational database. If that is the case, once you have resolved #name to its unique owner, I would create a one-to-many relationship between posting or comment and userids; that would allow a comment or post to reference more than one user.
TABLE: COMMENT_MENTIONEDUSERS
commentid
userid
I would recommend storing the comment as markdown since it's now quite widespread. In your case, "This is a comment for [#John](/user/johnID)".
Markdown is pretty standard and you shouldn't have an issue finding a package for editing / viewing.

how can we save the header of a datagridview in the database without adding a new row in the database?

This is what our form looks like:
InstructorsID CourseCode Section Surname FirstName MiddleName Date1 Date2 Date3 Date4 Date5 Date6 Date7 Date8 Date9 TotalAbsent Present EquivalentGrade
Alex Comp100 DCIT-1b Bancil Lenrick Malabanan Check Check Check Check Uncheck Uncheck Check Uncheck Check 3 6 83
The columns that has a name "DATE" are checkboxes and it represent the inputted value in the text box. We wanted to save the header of a datagridview in the database to the new fields that we added to the database.
And this is what our database looks like :
InstructorsID CourseCode Section Surname FirstName MiddleName DateA Date1 DateB Date2 DateC Date3 DateD Date4 DateE Date5 DateF Date6 DateG Date7 DateH Date8 DateI Date9 TotalAbsent Present EquivalentGrade
Alex Comp100 DCIT-1b Bancil Lenrick Malabanan 06/02/14 Check 06/03/14 Check 06/04/14 Check 06/05/14 Check 06/06/14 Uncheck 06/07/14 Uncheck 06/08/14 Check 06/09/14 Uncheck 06/10/14 Check 3 6 83
We want this to happen to our database. When you pressed the button save, the header will be saved in the database. The case is that when you pressed the save button and you look at your database you can see a new added row in the database . Can anyone please help us ! we've been trying to figure out what to do but until now we don't get to solved it!
It is fundamentally wrong to just "save from grid to database". Database is comprised of tables, relations between those tables, stored procedures, views etc. The data in the database must follow the atomicity principle. This basically means, that every transaction in database must be treated as a complete whole. This means, that if you want to do something in your database, that involves multiple inserts/deletes/updates this represents a transaction and if one of e.g. inserts fails, everything is revoked (this is called "database rollback"). If everything goes well, the database then applies the desired changes to the data via so-called "database commit".
The other, very important thing you must always keep in mind is that every database field should have only one value. So if you are storing the name of a person, you actually need two database fields: FirstName and LastName. If you want to complicate our life even further you obviously have to include MiddleName, MaidenLastName etc.
How is this relevant?
Gridviews are used to present data. They serve as a window into your data and usually make data useful. Sometimes people also populate gridviews in such way, that they create 1 column (let's call it Name) and then show FirstName+" "+LastName in that column. There is nothing wrong with this, but in your case, this presents a problem because you can create orange juce from an orange but cannot recreate the orange back from juice..
Datagridview is a WinForms control and is, as such able to present data from various datasources. Which database/datasource are you using?
I'm afraid you have provided insufficient information for my answer to be more thorough. I can however say,:
that your problem is probably more specific and you will have to provide additional details.
you shouldnt change the database schema based on user input
if you really need this kind of behavior, you will need to familiarize yourself with your database's DML (data manipulation language - for manipulating data) and DDL (data definition language - for changing schema, altering other schema-related issues).
Feel free to expand your question or to ask further.

User Management: Managing users in user-defined "groups", database schema and logistics

I'm a noob, development wise and logistically-wise.
I'm developing a site that lets people take a test...
My client wants the ability for a user with the roll/privledge "admin" (a step below a super-admin) to be allowed to create users and only see/edit the users that they create...
The users created in that "category" or group need some information that their superior provides.
For example, I log in as a "manager", I have the ability to invite people to take the test, and manage those people. Before adding those people, I will have filled out a short survey about myself...
Right now, the users that are invited will be asked some of the same questions as the manager. I'd like to cut down the redundancy by using the information put into the database by the manager and apply it to the invited users.
How do I set up my database to work with this criterion? I'm a little confused about how to do this! Let me know if I can add more details...
(This is a mysql and php app)
I am sure there are several ways to do this but here is one that comes to mind.
In the "users" database, I am sure you have a column to specify which manager is assigned to the user by some kind of user key. Well If this field has a value, then pull the info from that users (manager user) record.
Example:
table 'users'
key----name------managerid-----questionone------questiontwo----
1-------randy-----0------------------california----------c++--------------
2-------bob--------1------------------nevada------------------------------
Since record(key)1 has managerid == 0 then use questiontwo record to answer "Question 2".
Since record(key)2 has managerid == 1 then pull questiontwo from record(key)1 and use that for answer to question two.
You could either insert this information into the record or use it from the manager record dynamically as needed, which thought the space is still being used in the database, would be helpful since manager data might be updated and you might not want to have to update all records with that share the managerid wheh info is changed.
Make sense?

Resources