2013-03-29 63 views
7

Tôi có các bảng sau đây và mối quan hệ của chúng. Tôi đang lưu trữ dữ liệu json trong bảng client_services. Có cách nào để lấy các giá trị JSON bằng truy vấn mysql không. như:Làm cách nào để truy xuất dữ liệu JSON từ mysql?

select getJson("quota") as quota, client_id from client_services where service_id =1;  

HOẶC

Tôi có thể bình thường hóa client_services bảng hơn nữa?

dịch vụ:

+----+-----------------------+--------------------------------------------------------+ 
| id | name     | description           | 
+----+-----------------------+--------------------------------------------------------+ 
| 1 | MailBox    |              | 
| 2 | SMS     |              | 
| 3 | FTP     |              | 
+----+-----------------------+--------------------------------------------------------+ 

service_features:

+----+------------+----------------------------------+------------------------+ 
| id | service_id | name        | description   | 
+----+------------+----------------------------------+------------------------+ 
| 10 |   1 | Forwarding      | Forward Mail   | 
| 11 |   1 | Archive       | Archive Mail   | 
| 12 |   1 | WebMail       | NULL     | 
| 13 |   1 | IMAP        | NULL     | 
| 14 |   2 | Web SMS       | NULL     | 
+----+------------+----------------------------------+------------------------+ 

client_services:

+-----+-----------+------------+-------------------------------------------------------------------------------------------+ 
| id | client_id | service_id | service_values                   | 
+-----+-----------+------------+-------------------------------------------------------------------------------------------+ 
| 100 |  1000 |   1 |{ "quota": 100000,"free_quota":20000,"total_accounts":200,"data_transfer":1000000}   | 
| 101 |  1000 |   2 |{ "quota": 200 }                   | 
| 102 |  1000 |   3 |{ "data_transfer":1000000}                 | 
| 103 |  1001 |   1 |{ "quota": 1000000,"free_quota":2000,"total_accounts":200,"data_transfer":1000000}   | 
| 104 |  1001 |   2 |{ "quota": 500 }                   | 
| 105 |  1002 |   2 |{ "quota": 600 }                   | 
+-----+-----------+------------+-------------------------------------------------------------------------------------------+ 

client_feature_mappers:

+-----+-------------------+--------------------+-----------+ 
| id | client_service_id | service_feature_id | client_id | 
+-----+-------------------+--------------------+-----------+ 
|10000|    100|     10 |  1000| 
|10001|    100|     11 |  1000| 
|10002|    100|     12 |  1000| 
|10003|    100|     13 |  1000| 
|10004|    101|     14 |  1000| 
|10005|    103|     10 |  1001| 
|10006|    101|     11 |  1001| 
|10007|    101|     12 |  1001| 
|10008|    101|     13 |  1001| 
|10009|    105|     14 |  1002| 
+-----+-------------------+--------------------+-----------+ 
+1

Tại sao bạn muốn lưu trữ JSON thô trong bảng? Nó sẽ không có ý nghĩa hơn để lưu trữ dữ liệu trong một định dạng hợp lý hơn và xây dựng JSON lên ở một cấp độ cao hơn trong ngăn xếp? – david99world

Trả lời

15

Vì nhiều người đã đặt câu hỏi này cho cá nhân tôi, tôi nghĩ tôi sẽ trả lời câu hỏi này lần thứ hai. Dưới đây là a gist that has the complete SQL with SELECT, Migration and View Creationa live sql fiddle(tính khả dụng không được đảm bảo cho fiddle).

Hãy nói rằng bạn có bảng (tên: JSON_TABLE) như thế này:

ID CITY  POPULATION_JSON_DATA 
----------------------------------------------------------------------- 
1 LONDON  {"male" : 2000, "female" : 3000, "other" : 600} 
2 NEW YORK {"male" : 4000, "female" : 5000, "other" : 500} 

Để Chọn mỗi lĩnh vực json, bạn có thể làm:

SELECT 
    ID, CITY, 
    json_extract(POPULATION_JSON_DATA, '$.male') AS POPL_MALE, 
    json_extract(POPULATION_JSON_DATA, '$.female') AS POPL_FEMALE, 
    json_extract(POPULATION_JSON_DATA, '$.other') AS POPL_OTHER 
FROM JSON_TABLE; 

mà kết quả:

ID CITY  POPL_MALE POPL_FEMALE POPL_OTHER 
----------------------------------------------------------------- 
1 LONDON 2000  3000   600 
2 NEW YORK 4000  5000   500 

Đây có thể là một hoạt động tốn kém để chạy dựa trên kích thước dữ liệu của bạn và độ phức tạp của json. Tôi đề nghị sử dụng nó cho

  1. Migration của bảng để chia cơ sở dữ liệu (Xem Phụ lục 2-B trong ý chính)
  2. Ít nhất tạo ra một cái nhìn (Xem Phụ lục 2-C trong ý chính)

Coi chừng: Bạn có thể phải json bắt đầu với dấu ngoặc kép (chuyển đổi thành chuỗi):

"{"male" : 2000, "female" : 3000, "other" : 600}" 

Đã thử nghiệm với Mysql 5.7 trên Ubuntu và Mac OSX Sierra.

+0

(cộng 1) cho "sử dụng cho chỉ di chuyển dữ liệu" – user3581203

1

Cơ sở dữ liệu để lưu trữ và truy xuất dữ liệu chứ không phải định dạng dữ liệu. MySQL kết quả đầu ra mọi thứ trong dạng bảng và đó là cách nó hoạt động. Vì vậy, nếu bạn muốn có JSON, bạn cần tự chuyển đổi dữ liệu bảng này thành JSON, trong mã của bạn.

+0

Tôi cần truy vấn mysql truy xuất dữ liệu json, vì một số máy chủ như dovecot (Imap, pop server) truy vấn trực tiếp đến mysql, nếu không tôi đã thực hiện nó thông qua mã. Tôi đã gặp một số UDF Mysql như http://blog.kazuhooku.com/2011/09/mysqljson-mysql-udf-for-parsing-json.html. có đáng để cài đặt không. –

+0

@pankajghadge đây là loại kiến ​​trúc kỳ lạ, rõ ràng là bạn đang giải quyết vấn đề của mình với các công cụ sai. Nhưng bạn có thể viết thủ tục mysql sẽ định dạng dữ liệu dạng bảng thành JSON, nó không phải là khó. – Andrey

+0

tôi không có kinh nghiệm viết chức năng mysql. Tôi là điều về bình thường hóa bảng hơn nữa, nhưng nó sẽ làm tăng thời gian đầu ra truy vấn. –

2

Trước tiên, bạn cần lưu ý rằng mô hình của bạn ở trên không ở trong Biểu mẫu thông thường đầu tiên, có nghĩa là bạn chỉ nên có một giá trị duy nhất trong mỗi trường. Tuy nhiên, định nghĩa này phụ thuộc vào nhu cầu xử lý truy vấn ứng dụng của bạn.

Vì vậy, nếu tất cả những gì bạn muốn là đặt một bó dữ liệu JSON vào một trường và trả lại cho ứng dụng như hiện tại thì tốt. Bạn có thể trả về toàn bộ dữ liệu JSON và cho phép ứng dụng chọn các thuộc tính JSON mà nó muốn.

Nhưng nếu bạn có các truy vấn, như trong trường hợp của bạn, có tiêu chí hoặc biểu thức trường nhìn vào chi tiết của dữ liệu JSON, thì chắc chắn là không có. Nó sẽ là một cơn ác mộng trong phức tạp truy vấn và xử lý chậm.

Bạn có thể tiếp tục chuẩn hóa các bảng của mình để thay thế hoàn toàn cấu trúc dữ liệu JSON. Tuy nhiên, nếu ứng dụng của bạn cần lược đồ linh hoạt, có thể là lý do chính để sử dụng DBOS NOSQL, nhưng bạn đang mắc kẹt với MySQL, có hai giải pháp:

a) sử dụng MySQL 5.6 (hoặc MariaDB v. ??) cho NoSQL hỗ trợ (tôi đã không nhìn vào chi tiết) http://www.computerworld.com/s/article/9236511/MySQL_5.6_tackles_NoSQL_competitors MariaDB của cột năng động: https://kb.askmonty.org/en/dynamic-columns/

b) sử dụng mysql mà không có một sơ đồ rõ ràng, thấy ở đây một giải pháp thực hiện rất tốt, không có vấn đề khả năng mở rộng: http://backchannel.org/blog/friendfeed-schemaless-mysql

3

Bạn có thể sử dụng hàm MySQL SUBSTRING_INDEX để phân tách chuỗi JSON:

SELECT 
SUBSTRING_INDEX(
SUBSTRING_INDEX(
    SUBSTRING_INDEX(service_values, 'quota', -1), 
    '": ', -1), 
' ', 1) AS quota, 
client_id 
FROM client_services 
WHERE service_id=1; 
Các vấn đề liên quan