I wonder about the structure of the database and how it should be designed optimally.
Problem:
An application for publishing books, books is added by the administrator. There is a Cooperator module, when publishing a book to the platform, you can add a Cooperator. Cooperator has activation codes. The activation code allows the user to access content that has been tagged with a given Cooperator. You can purchase a subscription, a subscription gives you the opportunity to access books without the specified Cooperator. I do not know how to solve it correctly from the database side, to make it as optimal as possible, in addition, if the user does not activate the Cooperator code, he should not see these books at all.
Actual Database:
Book Entity:
Date Created
Date Updated
Id
Name
Categories
Cooperator
Cooperator Entity
Date Created
Date Updated
Id
Name
CodeBatches (One to Many)
Code Batche Entity:
Date Created
Date Updated
Id
Name
Access In Months
Cooperator (Many to One)
CodesActivation (One to Many)
Code Activation Entity
Date Created
Date Updated
Id
Status
Activation Code(Unique)
Related
So in a traditional database I might have 2 tables like users, company
id
username
companyid
email
1
j23
1
something#gmail.com
2
fj222
1
james#aol.com
id
ownerid
company_name
1
1
A Really boring company
This is to say that user 1 and 2 are apart of company 1 (a really boring company) and user 1 is the owner of this company.
I could easily issue an update statement in MySQL or Postgresql to update the company name.
But how could I model the same data from a NoSQL perspective, in something like Dynamodb or Mongodb?
Would each user record (document in NoSQL) contain the same company table data (id, ownerid (or is owner true/false, and company name)? I'm unclear how to update the record for all users containing this data then if the company name needed to be updated.
In case you want to save the company object as JSON in each field (for performance reasons), indeed, you have to update a lot of rows.
But best way to achieve this is to have a similar structure as you have above, in MySQL. NoSql schema depends a lot on the queries you will be making.
For example, the schema above is great for:
Find a particular user by username, along with his company name. First you need to query User by username (you can add an index), get the companyId and do another query on Company to fetch the name.
Let's assume company name changes often
In this case company name update is easy. To execute the read query, you need 2 queries to get your result (but they should execute fast)
Embedded company JSON would work better for:
Find all users from a specific city and show their company name
Let's assume company name changes very rarely
In this case, we can't use the "relational" approach, because we will do 1 query to fetch Users by city and then another query for all users found to fetch the company name
Using embedded approach, we need only 1 query
To update a company name, a full (expensive) scan is needed, but should be ok if done rarely
What if company name changes ofter and I want to get users by city?
This becomes tricky, NoSQL is not a replacement for SQL, it has it's shortcomings. Solution may be a platform dependent feature (from mongo, dynamodb, firestore etc.), an additional layer above (elasticSearch) or no solution at all (consider not using key-value NoSQL)
Depends on the programming language used to handle NoSQL objects/documents you have variety of ORM libraries to model your schema. Eg. for MongoDB plus JS/Typescript I recommend Mongoose and its subdocuments. Here is more about it:
https://mongoosejs.com/docs/subdocs.html
I am currently trying to model a MongoDB database structure where the entities are very complex in relation to each other.
In my current collections, MongoDB queries are difficult or impossible to put into a single aggregation. Incidentally, I'm not a database specialist and have been working with MongoDB for only about half a year.
To keep it as simple as possible but necessary, this is my challenge:
I have newspaper articles that contain simple keywords, works (oevres, books, movies), persons and linked combinations of works and persons. In addition, the same people appear under different names in different articles.
Later, on the person view I want to show the following:
the links of the person with name and work and the respective articles
the articles in which the person appears without a work (by name)
the other keywords that are still in the article
In my structure I want to avoid that entities such as people occur multiple times. So these are my current collections:
Article
id
title
keywordRelations
KeywordRelation
id
type (single or combination)
simpleKeywordId (optional)
personNameConnectionIds (optional)
workIds (optional)
SimpleKeyword
id
value
PersonNameConnection
id
personId
nameInArticleId
Person
id
firstname
lastname
NameInArticle
id
name
type (e.g. abbreviation, synonyme)
Work
id
title
To meet the requirements, I would always have to create queries that range over 3 to 4 tables. Is that possible and useful with MongoDB?
Or is there an easier way and structure to achieve that?
Is it possible to reference additional columns apart from the 'Code' and 'Name' columns when using a domain attribute in an entity?
E.g. A person entity has a code of '1' and a name of 'Smith' and a Gender of 'Male'
In a customer entity there is a domain value referencing the person entity which displays the following 1 {Smith}. The users would like an additional read only attribute which would copy the Gender value of 'Male' into the customer entity based on the domain value. Can this be done using out of the box MDS UI?
I know this is duplicate data and breaks normal form but for usability this would be useful. It would be the equivalent of referencing additional columns in an MS Access drop down list.
Many thanks in advance for any help
This is not possible with the standard UI. One option would be to develop a custom UI where you can handle these kind of requests.
If you want to stick with the standard product I can see a workaround but this is a bit of a "dirty" one.
You can misuse (abuse) the Name attribute of the Person entity by adding a business rule to the Person entity that generates the content of the Name attribute as a concatenation of multiple attributes. You of course need an additional attribute that serves as a place holder for the original Name. The concatenated field will then show in your customer entity.
One question that does come to mind is why a user would like/need to see the gender of a person in a customer list? As you have a separate Person entity I expect you to have multiple persons per customers. What would the gender of one person - even if it is the main contact - matter?
Dear helpers and saviors !
I'm trying to create some dynamic forms with Silex.
My objective is to have the user create a state in a existing country. I would like him/her to select a region (like Asia, Europe, America...), then select a country to which link the newly created state.
I have some "classic" and simple forms extending AbstractType, in which the user can select the country directly. I created a choice list based on a call to a DAO (database) to find all available countries. I would like to add a region choice_list field to reduce the number of available country (and reduce the database charge as well even if it isn't my main goal).
I've seen http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data, but it seem that we can't create subform for elements that are "parents" of the main class (or that i did not understood how), saying that the link is not stored in my object i would like to create. What i would like to do here is to add a field for the 2-level above (state->country->region), not direcly linked (a state have a country, and a country have a region) region.
I do not manage to imagine or code it properly, or even simply displaying.
Please note that i'll have to do it on several levels (state, city, and some other classes), and i would like to find a quite generic way to do it (understand not a ready solution for this particular example).
Any ideas ?
Please excuse my english, and thank you very much for your help !
For reference, here are my DB links between objects :
Region : ID and Name
Country : Codes, ID, Name and link to Region's ID
State : Codes, ID, Name and link to Country's ID
City : Name, ID and link to State's ID
I managed to do what i wanted.
I created supplementary forms, asking for filling each of the "parent" objects.
So in addition to my Types forms, i now have a selection a Select forms, allowing me to select Region, then Country, then State.
I have a SQL Server 2008 R2 database that contains a table that holds my entities from an ad.
It looks something like this :
Title
Price
CreatedDate
UpdatedDate
Description
EndDate
PublishedDate
StateOfProduct
Id
UserId
UserLocationId
Visits
CategoryId
TypeOfAd
AdminComment
ReviewedDate
AmountOfImages
UserPostCode
UserEmail
UserPhoneNr
UserPassword
OwnerType
AdminUserId
InactivatedDate
OldPrice
PriceLastChange
An Ad entity can have the following stages : Published, Waiting for review, Outdated.
Say that the ad is published and the customer decides to edit the ad, this means that the settings on the ad above will change. A change like this demands a new review and that means that the ad will go from Published to Waiting for review.
The problem with this is that when a ad is changed and is waiting for review it is not published anymore.
What I need is to let the ad be published with the old (reviewed) data and when the review is done of the updated ad it will switch places but keep the old id.
The question is how to handle this the right way?
I Suppose that I could have two identical tables to keep record count down and to make it simpler to find published ads but it will be a lot more work to use Entity Framework against two identical tables at the same time.
Another solution might be to add two extra columns in the Ads table that holds the version of the ad and the original adId. The flow will in this case be something like this :
Create Ad(id=1), originalId = null, version = null.
Review Ad(id=1)
Publish Ad(id=1), version = 1
Customer Updates Ad, new Ad(id=2) is created with version set to null(=waiting for review) and originalId = 1
Reviewed Ad(id=2) done, Ad(id=1) will be copied to a new records (id = 3 (or2)), originalId set to 1. Ad(id=2) will be moved/copied to Ad(id1), originalId = null, version = 2.
The ad table might however be vary large with this but it will be a lot easier to trace ads history.
I believe this could be done using many approaches, it's just a matter of preference. What I would do is make a new table named, say, ReviewedAds with int Id, int AdId, bit Reviewed. 1:many relationship with Ads table so AdId from this table is a foreign key and matches Id from Ads table. Then I would display only those ads whose Reviewed bit is set to '1'. Two records in ReviewedAds couldn't have the same AdId and Reviewed bit set to '1'.