How does no-sql handle relational data? - java

I know it is a non-relational database but this does not mean that relational data does not exist.
For example, I have a table that holds urls like this ( simplified ):
url | domain
and I have a table that holds domains like this ( simplified ):
domain | favicon_path
Because many different urls may have the same domain, I did not want to repeat the favicon_path for each domain when pulling the data for sending to the view.
Hence I used a simple ( simplified for example ) join command when I need the data.
"SELECT bookmarks.*, domains.favicon FROM bookmarks JOIN
domains ON bookmarks.domain=domains.domain"
How would I handle this scenario using no-sql?
I plan on implementing no-sql using indexedDB on the client ( javascript ) and MongoDB on the server ( java ).

If you want to use document-oriented DB, you can use this structure of documents:
URL_ID : {
"domain":"id_of_domain",
"another_staff": "..."
}
DOMAIN_ID : {
"favicon_path" : "path or id of another document",
"another_staff": "..."
}
So you can get document with URL_ID by id from database and then get document of type Domain.
ADDITION:
You can use the following approach for generating id. Create special document (like sequence) which will have only one field - current_value_of_sequence. Every insert to DB you have to get this sequence and increment it. Some DB like Couchbase have low-level support of this mechanism, which very efficient and thread-safety.

From years of work expierence in IT area, I would say most of the business models could be normalized as simple as these two types of data structure:
Entity info.
Entity list.
For example, in a book store business, we will have the Book entity, and many list that containing all of the books or a subset of the whole books.
With a NoSQL database, such as Redis or SSDB, the Book entity is stored with Key-Value, where key is the book sn, and value is the stringified book info(title, publish date, description, etc). While book list(list by publish date, list by price, etc) are stored in zset data type.

Related

Partial JSON update on DynamoDB

I have a simple dynamo table that consists of cookies and attributes:
customer
cookie
attribute_1
attribute_2
...
attribute_n
Right now, these attributes are variable and need to be updated upon receiving a partial JSON through and endpoint.
I made my mind into using the new JSON type field in DynamoDB (since that's our main datastore choice), and I intend to reshape the table into:
customer
cookie
attributes
Where attributes is just a JSON document.
Main issues:
I have no way of knowing which attributes are going to be added
I have no way ok knowing which items already exist (save from making an extra query)
I'd like to avoid a super complex code to do this
Main goal:
In an ideal world, there should be some way of having or not an item in dynamo and passing the primary key along with some JSON and then having the DB partially update the existing JSON.
So far I've seen this kind of code:
DynamoDB dynamo = new DynamoDB(new AmazonDynamoDBClient(...));
Table table = dynamo.getTable("people");
table.updateItem(
new UpdateItemSpec()
.withPrimaryKey("person_id", 123)
.withUpdateExpression("SET document.current_city = :city")
.withValueMap(new ValueMap().withString(":city", "Seattle")));
But I'd like to avoid making an extra query (to know if I need to create or update) and constructing all the update expressions.
Is there a way to do this?
Here is a full example just in case:
1) Receive the following JSON in the API:
{"name": "John"}
Expected dynamo attribute:
attributes={"name": "John"}
2) Receive the following JSON in the API:
{"age": 12}
Expected dynamo attribute:
attributes={"name": "John", "age": 12}
And so on. The primary key is constructed from the request cookie / customer.
My hopes for this existing comes from the fact that dynamo supports the smart updateItem (which I'm currently using) that allows to specify only some attributes to update or create an item.

Perform where condition in couchdb

Here is my database schema:
Database name: user
_id 74acd65e6eeb6d55809a950036000f50
_rev 1-f5ca343d0688d7a01b549e5c29a4a911
Budget dsds
user_Id abc123
Name ssdsd
Now what I want is to retrieve all the records who are having "user_Id":"ssdsd" using GWT.
Like in mysql: select * from user where user_Id=ssdsd
Please guide me in the following code
public String view(String user_id) throws IllegalArgumentException {
// TODO Auto-generated method stub
Session s1=new Session("127.0.0.1",5984);
Database db=s1.getDatabase("users");
return "";
Unfortunately I'm not familiar with GWT, but I think your question is more CouchDB-related.
If you plan on having one and exactly one document per user, then you should use the user_Id directly as the _id. This way you get the benefit of using the "primary" index of CouchDb to your advantage and enforce unique user ids at the same time.
It is good practice and a convention to also store the type of the document in the type property.
The document could look like this:
{
"_id": "user.abc123",
"type": "user",
"name": "ssdsd",
"budget": "dsds"
}
If you need to have multiple documents per user_Id, then you need to write a CouchDB view. You can read an introduction in the CouchDB Docs.
This would be some simple JavaScript code for the CouchDB map function:
function (doc) {
if (doc.user_Id) {
emit(doc.user_id, {budget: doc.budget});
}
}
You would then be able to query this view by calling the view with a key of "abc123", e.g. in the browser by calling this URL:
http://localhost:5984/users/_design/users/_view/users?key=[“abc123"]
P.S.: If you need authentication also, it might be worth considering to store the users in the built-in database _users. Just keep in mind that there are some restrictions in this system db: non-admins cannot read other users' documents in this db, and some special schema requirements have to be met when adding documents there.

How to design an exception logging table using HyperTable and access it via the Java client?

If I have the following table schema to log an exception (in standard SQL schema):
Table: ExceptionLog
Columns: ID (Long),
ExceptionClass (String),
ExceptionMessage (String),
Host (String),
Port (Integer),
HttpHeader (String),
HttpPostBody (String),
HttpMethod (String)
How would I design the same thing in HyperTable (specifically, what is the best approach for efficiency)? And, how would I code it using the HyperTable Java client?
What is ID - is it an auto-incremented unique ID? Hypertable does not have auto-increments, but uses random GUIDs for unique IDs if you don't want to provide your own ID. Here's a link with more information:
http://hypertable.com/documentation/developer_guide/#unique-cells
I would maybe combine Host and Port into a single column ("hypertable.com:8080"), but that's my personal preference.
Everything else looks fine. You can simply translate this to a CREATE TABLE statement in HQL:
CREATE TABLE ExceptionLog (ID, ExceptionClass, ExceptionMessage, Host, Port, HttpHeader, HttpPostBody, HttpMethod);
You might also want to have secondary indices, i.e. on ExceptionClass, if you have frequent queries like
SELECT ExceptionClass FROM ExceptionLog WHERE ExceptionClass = "Segfault";
Secondary indices are documented here: http://hypertable.com/documentation/developer_guide/#secondary-indices
Here's a sample which shows how to use the Java client. It's fairly simple: https://github.com/cruppstahl/hypertable/blob/v0.9.6/src/java/ThriftClient/org/hypertable/thrift/BasicClientTest.java

Mongodb database Schema design tips [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mongodb database Schema Design with shared data
Hi I am newbie to mongodb.I am using java.
I have 4 tables Tenant,system,authorization in my relational table.
Something like this.
Table Fields
Tenant Tenant_ID(PK), Tenant_INFO
System System_ID(PK), System_Info
Authorization System_ID, Autho_Info.
System_prop System_ID, Prop_Info, Tenant_ID
In System_prop table, Tenant_ID refers the Tenant Table Tenant_ID (PK), System_ID refers the System Table System_ID.
In Authorization table, System_ID refers System tabel System_ID
I am switching my database from relational to mongodb. First thing I need to do is Schema design.
Query I need to do is:
SELECT D.Prop_Info, D.System_ID, A.Tenant_Info From TENANT A ,System_prop D, SYSTEM B, Where D.System_ID = B.System_ID AND D.Tenant_ID = A.Tenant_ID
SELECT C.System_ID, C.auth_Info, B.System_ID FROM Authorization C, SYSTEM B WHERE C.System_ID = B.System_ID
Can anyone help me how to design these tables as collections in mongodb?
Do i need to embed r use dbref? Help me to design the schema for this.
From the schema information you provided, it looks like you have a many-to-many relationship between Tenant and System (through the JOIN table System_prop), and a one-to-many relationship between System and Authorization.
In MongoDB, both of these types of relationships can be implemented using array fields. This is how you could set up your System collection:
{
System_Info: ...,
Tenant: [
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
},
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
} ],
Authorization: [
{
Auth_Id: ...,
Auth_Info: ...
},
{
Auth_Id: ...,
Auth_Info: ...
} ]
}
However, for the Tenant info, you will now have de-normalized duplicate information, i.e. the same Tenant document appears in different System documents. It is up to your application to ensure consistency.
As for the queries you mentioned: It looks like there is some information missing. For the first query, you're joining on the Tenant_Id but not requesting any information from the Tenant table. The second one requests Prop_Info from the Authorization table but that table doesn't have Prop_Info. Should that be A.Autho_Info instead? So you might want to double-check these queries.
Here are some additional resources about schema design in MongoDB that are worth a read:
http://www.mongodb.org/display/DOCS/Schema+Design
https://openshift.redhat.com/community/blogs/designing-mongodb-schemas-with-embedded-non-embedded-and-bucket-structures
In the end, it depends on your application and most frequent queries how exactly you choose to store your data, and the example above is just one way to set up your schema.
You are still thinking in relational databases. MongoDB, however, is a document-oriented database.
artificial ID numbers are usually not needed, because every document automatically has a _id field, which is a GUID (as good as guaranteed to be globally unique).
relation tables should not be used in MongoDB. n-type relations are made with arrays fields instead. So when 1 system has N authorizations it uses, your system document should have a field "authorization" which is an array of the object IDs of the authorizations it has. Yes, that would be a horrible violation of the normalization rules of relational databases. But you don't have a relational database here. In MongoDB it is practical to represent N-relations with arrays, because arrays are transparent to the query language.

The best way to import(merge)-export java db database

I have let's say two pc's.PC-a and PC-b which both have the same application installed with java db support.I want from time to time to copy the data from the database on PC-a to database to PC-b and vice-versa so the two PC's to have the same data all the time.
Is there an already implemented API in the database layer for this(i.e 1.export-backup database from PC-a 2.import-merge databases to PC-b) or i have to do this in the sql layer(manually)?
As you mention in the comments that you want to "merge" the databases, this sounds like you need to write custom code to do this, as presumably there could be conficts - the same key in both, but with different details against it, for example.
In short: You can't do this without some work on your side. SalesLogix fixed this problem by giving everything a site code, so here's how your table looked:
Customer:
SiteCode varchar,
CustomerID varchar,
....
primary key(siteCode, CustomerID)
So now you would take your databases, and match up each record by primary key. Where there are conflicts you would have to provide a report to the end-user, on what data was different.
Say machine1:
SiteCode|CustomerID|CustName |phone |email
1 XXX |0001 |Customer1 |555.555.1212 |darth#example.com
and on machine2:
SiteCode|CustomerID|CustName |phone |email
2 XXY |0001 |customer2 |555.555.1213 |darth#nowhere.com
3 XXX |0001 |customer1 |555.555.1212 |darth#nowhere.com
When performing a resolution:
Record 1 and 3 are in conflict, because the PK matches, but the data doesnt (email is different).
Record 2 is unique, and can freely exist in both databases.
There is NO way to do this automatically without error or data corruption or referential integrity issues.
I guess you are using Java DB (aka Derby) - in which case, assuming you just can't use a single instance, you can do a backup/restore.
Why dont you have the database on one pc. and have all other pc's request data from the host pc

Categories