當前位置:首頁 » 數據倉庫 » json做資料庫
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

json做資料庫

發布時間: 2023-04-16 14:42:07

『壹』 如果將json格式數據存儲到類似mysql這樣的關系型資料庫中,怎麼查

在MySQL與PostgreSQL的對比中,PG的JSON格式支持優勢總是不斷被拿來比較。其實早先MariaDB也有對非結構化的數據進行存儲的方案,稱為dynamic column,但是方案是通過BLOB類型的方式來存儲。這樣導致的問題是查詢性能不高,不能有效建立索引,與一些文檔資料庫對比,優勢並不大,故在社區的反應其實比較一般。當然,MariaDB的dynamic column功能還不僅限於非結構化數據的存儲,但不在本文進行展開。
MySQL 5.7.7 labs版本開始InnoDB存儲引擎已經原生支持JSON格式,該格式不是簡單的BLOB類似的替換。原生的JSON格式支持有以下的優勢:
JSON數據有效性檢查:BLOB類型無法在資料庫層做這樣的約束性檢查
查詢性能的提升:查詢不需要遍歷所有字元串才能找到數據
支持索引:通過虛擬列的功能可以對JSON中的部分數據進行索引
首先我們來看如何在MySQL中使用原生的JSON格式:
mysql> create table user ( uid int auto_increment,
-> data json,primary key(uid))engine=innodb;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into user values (NULL,
-> '{"name":"David","mail":"[email protected]","address":"Shangahai"}');
Query OK, 1 row affected (0.00 sec)

mysql> insert into user values (NULL,'{"name":"Amy","mail":"[email protected]"}');
Query OK, 1 row affected (0.00 sec)

可以看到我們新建了表user,並且將列data定義為了JSON類型。這意味著我們可以對插入的數據做JSON格式檢查,確保其符合JSON格式的約束,如插入一條不合法的JSON數據會報如下錯誤:
mysql> insert into user values (NULL,"test");
ERROR 3130 (22032): Invalid JSON text: "Invalid value" at position 2 in value (or column) 'test'.

此外,正如前面所說的,MySQL 5.7提供了一系列函數來高效地處理JSON字元,而不是需要遍歷所有字元來查找,這不得不說是對MariaDB dynamic column的巨大改進:
mysql> select jsn_extract(data, '$.name'),jsn_extract(data,'$.address') from user;
+-----------------------------+-------------------------------+
| jsn_extract(data, '$.name') | jsn_extract(data,'$.address') |
+-----------------------------+-------------------------------+
| "David" | "Shangahai" |
| "Amy" | NULL |
+-----------------------------+-------------------------------+
2 rows in set (0.00 sec)

當然,最令人的激動的功能應該是MySQL 5.7的虛擬列功能,通過傳統的B+樹索引即可實現對JSON格式部分屬性的快速查詢。使用方法是首先創建該虛擬列,然後在該虛擬列上創建索引:
mysql> ALTER TABLE user ADD user_name varchar(128)
-> GENERATED ALWAYS AS (jsn_extract(data,'$.name')) VIRTUAL;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> select user_name from user;
+-----------+
| user_name |
+-----------+
| "Amy" |
| "David" |
+-----------+
2 rows in set (0.00 sec)

mysql> alter table user add index idx_username (user_name);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0

然後可以通過添加的索引對用戶名進行快速的查詢,這和普通類型的列查詢一樣。而通過explain可以驗證優化器已經選擇了在虛擬列上創建的新索引:

mysql> explain select * from user where user_name='"Amy"'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL
type: ref
possible_keys: idx_username
key: idx_username
key_len: 131
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)

可以發現MySQL 5.7對於JSON格式堪稱完美,相信PostgreSQL陣營需要尋找新的策略來「攻擊」MySQL了吧。如無意外,還是會停留在優化器這塊,畢竟這塊是目前MySQL必須要克服的最大問題,好在MySQL團隊已經在重構優化器代碼,相信更好的優化器將會在下一個版本中全面爆發。而一大堆文檔資料庫們已經哭暈在廁所了吧。

『貳』 如何把獲取的json數據插入資料庫

直接varchar或者text之類的類型即可插入。在Mysql5.7或以上可以支持JSON數據類型。其他的資料庫你可以參考他的不同版本,考慮是否支持JSON數據類型,如果不支持就用字元串類型。但是要考慮長度。
PS:如果是用客戶端鏈接,那麼就算資料庫支持,那客戶端也得是最新版支持JSON的,要不然資料庫支持,工具以為不支持!

『叄』 從jsp頁面上傳 excel文件 存到資料庫 用json做

不明白為啥指定json,我的建議是:
1、STRUTS文件標簽選擇並上傳EXCEL文件,示例代碼:
<html:form action="/uploadExcelFile/UploadExcelFileAction.go" enctype="multipart/form-data" method="post" onsubmit="return confirm_save()">
<table border="0" cellpadding="0" cellspacing="5" align="center" style="margin:50">
<tr>
<td align="right" nowrap > 請選擇Excel文件(.<%=excelType%>):</td>
<td align="right" colspan="3" valign="middle" nowrap ><html:file property="aircraftExcel" size="200" style="width:400;height:25" value=""></html:file></td>
</tr><tr>
<td></td>
<td align="right">Excel文件中櫻吵鋒標題(表頭)占行:</td>
<td align="left"><input name="topicRow" value="0" style="width:50" onKeyUp="value=value.replace(/[\D]/g,'')"/></td>
<TD align="right" nowrap title="上傳"><html:submit value="開始更新" style="height:25; width:70"></html:submit></TD>
</tr>
</table>
</html:form>
2、UploadExcelFileAction接收、寫入後台指定目錄(脊晌局部代碼)
FileOutputStream fos = null;
try {
//得到文件數據(數組)
byte[] fileDate = ff.getFileData();
//得到服務碰慎器硬碟文件夾的絕對路徑
ServletContext application = this.getServlet().getServletContext();
String realPath = application.getRealPath("/");
if(excelType==null||excelType.equals("xlsx"))//默認生成2007以後版本格式
fos = new FileOutputStream(realPath+"aircraftExcelTable.xlsx");
else
fos = new FileOutputStream(realPath+"aircraftExcelTable.xls");
fos.write(fileDate);
fos.close();
if(excelType==null||excelType.equals("xlsx"))//默認生成2007以後版本格式
num=ReadExcelSaveToDB.ReadAndSaveNew(realPath+"aircraftExcelTable.xlsx",topicNumber);
else
num=ReadExcelSaveToDB.ReadAndSave(realPath+"aircraftExcelTable.xls",topicNumber);
if(num==-1){
session.setAttribute("forwardPage", currentPage);
session.setAttribute("prompt", "文件傳輸失敗或無法連接資料庫!");
return mapping.findForward("promptpage");
}else if(num==-2){
session.setAttribute("forwardPage", currentPage);
session.setAttribute("prompt", "Excel文件大於1000條或不能識別!重新製作Excel文件。");
return mapping.findForward("promptpage");
}else if(num==-3){
session.setAttribute("forwardPage", currentPage);
session.setAttribute("prompt", "Excel文件中包含非法字元(非數字),請修正後重試。");
return mapping.findForward("promptpage");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
3、解析讀取表數據(POI)並存入資料庫(局部代碼)
public static int ReadAndSave(String path,String topicNumber){
try {
File file=new File(path);
FileInputStream fs=new FileInputStream(file);
@SuppressWarnings("resource")
HSSFWorkbook workbook=new HSSFWorkbook(fs);
//一共有幾張表
int sheet_num=workbook.getNumberOfSheets();
setSheetNumber(0);
setProcess(0);//開始
//循環每個表
for(int i=0;i<sheet_num;i++){
HSSFSheet sheet=workbook.getSheetAt(i);
setSheetNumber(i+1);
if(sheet!=null&&sheet.getPhysicalNumberOfRows()!=0){
int topicNumberNum=Integer.parseInt(topicNumber);//越過首行的標題(如果有)
totalNumber=sheet.getPhysicalNumberOfRows()-topicNumberNum;
//循環各個行
for(int j=sheet.getFirstRowNum()+topicNumberNum;j<=sheet.getPhysicalNumberOfRows();j++){
HSSFRow row=sheet.getRow(j);
String aircraft=null;
//String aircraftType=null;
Double takeoffWeight=0.00;
Double payloadMax2=0.00;
int seatNumberMax2=0;
if(row!=null&&row.getPhysicalNumberOfCells()!=0){
switch(row.getCell(0).getCellType()){
case Cell.CELL_TYPE_STRING:
aircraft=(row.getCell(0).getStringCellValue()).trim();
break;
case Cell.CELL_TYPE_NUMERIC:
aircraft=String.valueOf(row.getCell(0).getNumericCellValue()).trim();
break;
}
//繼續處理其他單元格、行

//存入資料庫
AircraftTableActionForm atb=new AircraftTableActionForm();
if(aircraft!=null&&!aircraft.equals("")){
atb.setAircraft(aircraft);
//set其他值
updateByExcel(atb)!=-1

}

『肆』 資料庫存json 缺點

json數據僅僅只能用於展示display,如果用於條件查詢,數據更新其效率是很低的,而且難於優化,不要嘗試在json欄位上進行查詢優化。
雖然mysql5.7支持了json類型,但mysql作為關系型資料庫,對標准化的column-per-value支持更好,包括數據類型限制、長度限制,唯一索引限制,查詢索引優化,外鍵關聯,關聯查詢支持,運算支持等,這些都是json中key無法達到的。
將常用的查詢欄位從json數據中剝離出來形成單獨的欄位,雖然可以改善查詢問題,但你最好有先見之明,如果後期進行剝離就會涉及代碼修改和數據遷移,遇到多版本的話,還可能出現數據冗餘的問題,處理不好還會出現數據不一致問題,並不僅僅這么簡單,一定慎用。
存儲json的text類型性能並不樂觀。
大JSON的解析性能同樣不樂觀,而且對於中文數據,純JSON太占空間了。

『伍』 LowDB 輕量級 JSON 本地資料庫

作為輕量級的本地存儲方式,對於構建不依賴服務斗旁器的小型項空雀橡目,用LowDB存儲和管理數據是十分理想的選擇。在Nodejs, Electron and browser等一些小型項目中經常能看到LowDB的身影。

https://github.com/typicode/lowdb

npm install lowdb

或者:

yarn add lowdb

const low = require('lowdb');

const FileSync = require('lowdb/adapters/FileSync'); // 有多種適配器可選擇


const adapter = new FileSync('db.json'); // 申明一個適配器

const db = low(adapter);


db.defaults({posts: [], user: {}, count: 0})

.write();


db.get('posts')

.push({id: 1, title: 'lowdb is awesome'})

.write()


db.set('user.name', 'typicode')

.write()


db.update('count', n => n + 1)

.write()

運行程序會在項目中添加db.json文件,裡面存儲了添加的數據:

{

"posts": [

{

"id": 1,

"title": "lowdb is awesome"

}

],

"user": {

"name": "typicode"

},

"count": 1

}

lowdb是基於lodash構建的,所以可以使用任何lodash強大的函數,比如: _.get() 和 _.find(),並且可以串聯地使用:

db.get('users')

.find({sex: 'male'})

.value()

函數 功能

low(adapter) 返回一個具有特定屬性和功能的 lodash chain

db.[...].write() / .value() 寫 / 讀數據

db.getState() / .setState() 獲取 / 設置資料庫的狀態

db._ 資料庫lodash的實例,可以利用這個添加自己的函數或者第三方的mixins,比如lodash-id

db._.mixin({

second: function(array) {

return array[1]

}

})

db.get('posts')

.second()

.value()

針對lowdb自帶的適配器:FileSync、FileAsync 和 LocalBrowser,有以下可選歲轎參數:

defaultValue: 文件不存在時的默認值;

serialize/deserialize: 寫之前和讀之後的操作。

const adapter = new FilSync('db.json',{

serialize: (data) => encrypt(JSON.stringify(data)),

deserialize: (data) => JSON.parse(decrypt(data))

})

可以直接使用lodash的函數進行查詢。需要注意的是有些操作可能會導致原數據被修改,為了避免這種誤操作,需要使用 .cloneDeep(),操作都是惰性的,只有調用 .value()或 .write()後才會正式執行。

檢查users是是否存在

db.has('users')

.value()

設置users

db.set('users', [])

.write()

排序、選擇

db.get('users')

.filter({sex: 'male'})

.sortBy('age')

.take(5)

.value()

獲取特定欄位

db.get('users')

.map('name')

.value()

獲取數量

db.get('users')

.size()

.value()

獲取特定信息

db.get('users[0].name')

.value()

更新信息

db.get('users')

.find({name: 'Tom'})

.assign({name: 'Tim'})

.write()

刪除信息

db.get('users')

.remove({name: 'Time'})

.write()

移除屬性

db.unset('users.name)

.write()

深拷貝

db.get('users')

.cloneDeep()

.value()

可以使用 shortid 和 lodash-id 為資料庫中的每一條記錄創建唯一的id索引,然後通過id檢索操作記錄:

const shortid = require('shortid')


const postId = db

.get('posts')

.push({ id: shortid.generate(), title: 'low!' })

.write()

.id


const post = db

.get('posts')

.find({ id: postId })

.value()

const lodashId = require('lodash-id')

const FileSync = require('lowdb/adapters/FileSync')


const adapter = new FileSync('db.json')

const db = low(adapter)


db._.mixin(lodashId)


// We need to set some default values, if the collection does not exist yet

// We also can store our collection

const collection = db

.defaults({ posts: [] })

.get('posts')


// Insert a new post...

const newPost = collection

.insert({ title: 'low!' })

.write()


// ...and retrieve it using its id

const post = collection

.getById(newPost.id)

.value()

low( ) 函數接受自定義的Adapter

class MyStorage {

constructor() {

// ...

}


read() {

// Should return data (object or array) or a Promise

}


write(data) {

// Should return nothing or a Promise

}

}


const adapter = new MyStorage(args)

const db = low(adapter);

==============================================

英文官網介紹,更加簡潔

Lowdb 3 is a pure ESM package. If you're having trouble importing it in your project, please read this.

You can use TypeScript to type check your data.

You can also add lodash or other utility libraries to improve lowdb.

For CLI, server and browser usage, see examples/ directory.

Lowdb has two classes (for asynchronous and synchronous adapters).

Calls adapter.read() and sets db.data .

Note: JSONFile and JSONFileSync adapters will set db.data to null if file doesn't exist.

Calls adapter.write(db.data) .

Holds your db content. If you're using the adapters coming with lowdb, it can be any type supported by JSON.stringify .

For example:

Adapters for reading and writing JSON files.

In-memory adapters. Useful for speeding up unit tests.

Synchronous adapter for window.localStorage .

Adapters for reading and writing text. Useful for creating custom adapters.

If you've published an adapter for lowdb, feel free to create a PR to add it here.

You may want to create an adapter to write db.data to YAML, XML, encrypt data, a remote storage, ...

An adapter is a simple class that just needs to expose two methods:

For example, let's say you have some async storage and want to create an adapter for it:

See src/adapters/ for more examples.

To create an adapter for another format than JSON, you can use TextFile or TextFileSync .

For example:

Lowdb doesn't support Node's cluster mole.

If you have large JavaScript objects ( ~10-100MB ) you may hit some performance issues. This is because whenever you call db.write , the whole db.data is serialized using JSON.stringify and written to storage.

Depending on your use case, this can be fine or not. It can be mitigated by doing batch operations and calling db.write only when you need it.

If you plan to scale, it's highly recommended to use databases like PostgreSQL or MongoDB instead.

『陸』 json 存儲在資料庫中用什麼格式

JSON的格式非常簡單:名稱/鍵值。之前MySQL版本裡面要實現這樣的存儲,要麼用VARCHAR要麼用TEXT大文本。 MySQL5.7發布後,專門設計了JSON數據類型以及關於這種類型的檢索以及其他函數解析。我們先看看MySQL老版本的JSON存取。

『柒』 如何將json數據轉化為資料庫文件

從json數組中得到java數組,可以對該數組進行肢缺野轉化,如將JSONArray轉化為String型、Long型、Double型歷喊、Integer型、Date型等等。扮察

分別採用jsonArray下的getString(index)、getLong(index)、getDouble(index)、getInt(index)等方法。
同樣,如果要獲取java數組中的元素,只需要遍歷該數組。
Java代碼 收藏代碼
/**
* 將json數組轉化為Long型
* @param str
* @return
*/
public static Long[] getJsonToLongArray(String str) {
JSONArray jsonArray = JSONArray.fromObject(str);
Long[] arr=new Long[jsonArray.size()];
for(int i=0;i<jsonArray.size();i++){
arr[i]=jsonArray.getLong(i);
System.out.println(arr[i]);
}
return arr;
}
/**
* 將json數組轉化為String型
* @param str
* @return
*/
public static String[] getJsonToStringArray(String str) {
JSONArray jsonArray = JSONArray.fromObject(str);
String[] arr=new String[jsonArray.size()];
for(int i=0;i<jsonArray.size();i++){
arr[i]=jsonArray.getString(i);
System.out.println(arr[i]);
}
return arr;
}
/**
* 將json數組轉化為Double型
* @param str
* @return
*/
public static Double[] getJsonToDoubleArray(String str) {
JSONArray jsonArray = JSONArray.fromObject(str);
Double[] arr=new Double[jsonArray.size()];
for(int i=0;i<jsonArray.size();i++){
arr[i]=jsonArray.getDouble(i);
}
return arr;
}
/**
* 將json數組轉化為Date型
* @param str
* @return
*/
public static Date[] getJsonToDateArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);
Date[] dateArray = new Date[jsonArray.size()];
String dateString;
Date date;
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < jsonArray.size(); i++) {
dateString = jsonArray.getString(i);
try {
date=sdf.parse(dateString);
dateArray[i] = date;
} catch (Exception e) {
e.printStackTrace();
}
}
return dateArray;
}

public static void main(String[] args) {

JSONArray jsonLongs = new JSONArray();
jsonLongs.add(0, "111");
jsonLongs.add(1, "222.25");
jsonLongs.add(2, new Long(333));
jsonLongs.add(3, 444);

Long[] log=getJsonToLongArray(jsonLongs.toString());
for(int i=0;i<log.length;i++){
System.out.println(log[i]);
}

JSONArray jsonStrs = new JSONArray();
jsonStrs.add(0, "2011-01-01");
jsonStrs.add(1, "2011-01-03");
jsonStrs.add(2, "2011-01-04 11:11:11");

Date[] d=getJsonToDateArray(jsonStrs.toString());
for(int i=0;i<d.length;i++){
System.out.println(d[i]);
}
}
/*結果如下:
* 111
* 222
* 333
* 444
*
* Sat Jan 01 00:00:00 CST 2011
* Mon Jan 03 00:00:00 CST 2011
* Tue Jan 04 00:00:00 CST 2011
*/

『捌』 如何將從介面取到的json數據存入mysql資料庫

mysql資料庫建立表,存儲json欄位用text類型
然後從介面中獲取JSON數據,轉成STRING格式,直接插入到這個欄位就可以了。

『玖』 java解析json格式文件,再保存在資料庫怎麼做

java解析json格式文件,再保存在資料庫的方法:

1:定義一個實體類

2:用json lib將json字元串轉為Java對象

3:用jdbc或hibernate將java對象存入資料庫

直接讀寫文件,再把讀出來的文件內容格式化成json,再用JDBC、Mybatis或者其他框架將json數據存入資料庫。

假設實體類是這樣的:

publicclassElectSet{
publicStringxueqi;
publicStringxuenian;
publicStringstartTime;
publicStringendTime;
publicintmenshu;
publicStringisReadDB;
//{"xueqi":,"xuenian":,"startTime":,"endTime":,"renshu":,"isReadDB":}
publicStringgetXueqi(){
returnxueqi;
}
publicvoidsetXueqi(Stringxueqi){
this.xueqi=xueqi;
}
publicStringgetXuenian(){
returnxuenian;
}
publicvoidsetXuenian(Stringxuenian){
this.xuenian=xuenian;
}
publicStringgetStartTime(){
returnstartTime;
}
publicvoidsetStartTime(StringstartTime){
this.startTime=startTime;
}
publicStringgetEndTime(){
returnendTime;
}
publicvoidsetEndTime(StringendTime){
this.endTime=endTime;
}
publicintgetMenshu(){
returnmenshu;
}
publicvoidsetMenshu(intmenshu){
this.menshu=menshu;
}
publicStringgetIsReadDB(){
returnisReadDB;
}
publicvoidsetIsReadDB(StringisReadDB){
this.isReadDB=isReadDB;
}

}

有一個json格式的文件,存的信息如下:


Sets.json:
{"xuenian":"2007-2008","xueqi":"1","startTime":"2009-07-1908:30","endTime":"2009-07-2218:00","menshu":"10","isReadDB":"Y"}

具體操作:


/*
*取出文件內容,填充對象
*/
publicElectSetfindElectSet(Stringpath){
ElectSetelectset=newElectSet();
Stringsets=ReadFile(path);//獲得json文件的內容
JSONObjectjo=JSONObject.fromObject(sets);//格式化成json對象
//System.out.println("------------"jo);
//Stringname=jo.getString("xuenian");
//System.out.println(name);
electset.setXueqi(jo.getString("xueqi"));
electset.setXuenian(jo.getString("xuenian"));
electset.setStartTime(jo.getString("startTime"));
electset.setEndTime(jo.getString("endTime"));
electset.setMenshu(jo.getInt("menshu"));
electset.setIsReadDB(jo.getString("isReadDB"));
returnelectset;
}
//設置屬性,並保存
publicbooleansetElect(Stringpath,Stringsets){
try{
writeFile(path,sets);
returntrue;
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
returnfalse;
}
}
//讀文件,返回字元串
publicStringReadFile(Stringpath){
Filefile=newFile(path);
BufferedReaderreader=null;
Stringlaststr="";
try{
//System.out.println("以行為單位讀取文件內容,一次讀一整行:");
reader=newBufferedReader(newFileReader(file));
StringtempString=null;
intline=1;
//一次讀入一行,直到讀入null為文件結束
while((tempString=reader.readLine())!=null){
//顯示行號
System.out.println("line"line":"tempString);
laststr=laststrtempString;
line;
}
reader.close();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(reader!=null){
try{
reader.close();
}catch(IOExceptione1){
}
}
}
returnlaststr;
}

將獲取到的字元串,入庫即可。

『拾』 資料庫基礎——JSON

存儲JSON文檔所需的空間與LONGBLOB或LONGTEXT大致相同;存儲在JSON列中的任何JSON文檔的大小都限制為max_allowed_packet系統變數的值。可以使用JSON_STORAGE_SIZE( )函數獲取存儲JSON文檔所需的空間量。

["ade", 12, null, true, false]

{"k1": "value", "k2": 2}

[99, [78, "e"], {"k1": 1, "k2": "a"}, "de"]

{"k1": 1, "k2": [10, "s"]}

使用JSON路徑表達式選擇JSON文檔中的值。