-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathSystem-Design.mm
906 lines (868 loc) · 108 KB
/
System-Design.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
<map version="1.0.1">
<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->
<node CREATED="1553774318680" ID="ID_618237012" MODIFIED="1553774334536" TEXT="DB Design">
<node CREATED="1553774354186" ID="ID_1763710445" MODIFIED="1553774417667" POSITION="right" TEXT="原则">
<node CREATED="1553774548298" ID="ID_258425531" MODIFIED="1553774554870" TEXT="遵循事项">
<node CREATED="1553774420674" ID="ID_1570675559" MODIFIED="1553774519927">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
数据库设计的时候,要以数据模型清晰,正确为主,乍看上去可能操作会麻烦点,但是对于理解,维护,扩展来说是有利的。
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553774527754" ID="ID_1987383862" MODIFIED="1553774545500" TEXT="避免事项">
<node CREATED="1553774574546" ID="ID_1816124523" MODIFIED="1553774601908">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
不要一直想着不方便查询,很多所谓的方便查询只是在当时的业务情况下,说白点就是为了当时业务的某些功能方便操作,曾经看到过,页面长什么样数据库就长什么样的设计。可是,业务变化起来比翻书还快,上线第二天可能功能就变了,你所谓方便查询(操作)的数据库设计,马上就破功了,难道你把数据库又调整为方便这次业务操作的设计?第二天又变了呢?所以,千万不要为了一时的方便,让数据库和业务紧紧的耦合在一起。
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1553774606762" ID="ID_1970548572" MODIFIED="1553774630732">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
数据库表,字段,关系的定义必须明确,不能在A业务下代表一个意思,在B业务下又是另外一个意思。程序中充满了【如果xx业务,就这样取数据,如果yy业务就那样取数据】。更狠一点的是,比如一个字段的名称是【storeId】,正常来说我们会毫不犹豫的认为这就是店铺ID,可是真的就有业务保存的不是店铺ID,一点都没有夸张!想下你经常抱怨IF-ElSE太多,会不会就是这样的设计导致的?
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553774660194" ID="ID_1564969905" MODIFIED="1553774665053" TEXT="总结">
<node CREATED="1553774667362" ID="ID_380743728" MODIFIED="1553774697508">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
在实际开发中,很容易碰到数据关系混乱,逻辑混乱,表中字段的值一定要看具体业务,看了代码才知道保存了什么值,一定要看了代码才知道他们是如何建立关系的,在这种情况下,你就有改不完的Bug,做不完的工作。而且,有谁能清晰的记得每个业务的规则,从而知道MySql数据库中数据保存的规则?
</p>
<p>
</p>
<p>
一句话,铁打的数据,流水的业务,只有数据清晰,才能开展业务;数据库粒度越细,越是与业务无关,反而越容易处理业务,越容易维护和扩展,至于不方便询,有很多种解决方案,谁说一定要到MySql数据库中查询?可以将数据整合MongoDB,ElasticSearch等数据库,再去查询。
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1553774712267" ID="ID_1099042292" MODIFIED="1555743099258" POSITION="left" TEXT="数据库设计">
<node CREATED="1553774898338" ID="ID_1111956657" MODIFIED="1553774915746" TEXT="SKU与规格(Variation)">
<node CREATED="1553774926850" ID="ID_725865043" MODIFIED="1553774931314" TEXT="SKU">
<node CREATED="1553774936066" ID="ID_899920802" MODIFIED="1553774949979">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
在很多系统中,商品规格都是用SKU表示,SKU真的是规格吗?查阅很多资料后发现,SKU是【库存】单元,是用来追踪库存的最小单位。SKU表示指定的物品放在指定的位置,SKU的核心包含两部分,即:物品+存放位置。
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1553776168344" ID="ID_1275984726" MODIFIED="1553776192009" TEXT="参考:https://www.lokad.com/stock-keeping-unit-(SKU)-definition">
<node CREATED="1553775488554" FOLDED="true" ID="ID_224574291" MODIFIED="1587782356287" TEXT="STOCK-KEEPING UNIT (SKU) DEFINITION">
<node CREATED="1587782280153" ID="ID_384362600" MODIFIED="1587782299561">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">In the field of inventory management, a stock-keeping unit or SKU refers to a specific item stored to a specific location. The SKU is intended as the most disaggregated level when dealing with inventory. All units stored in the same SKU are supposed to be indistinguishable. Introducing the notion of SKU simplifies most inventory control operations. SKU are sometimes used to refer to intangible items such as warranties, however, in this article we focus on SKUs that have a tangible counterpart.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /></font>
</p>
<h2 class="separator" style="margin-top: 0px; margin-bottom: 0; font-weight: 400; line-height: 1.2; font-size: 32px; color: rgb(248, 117, 81); font-family: Open Sans, Helvetica, Arial, sans-serif; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">
<a class="headeranchor" id="SKUs_vs_products_0" href="https://www.lokad.com/stock-keeping-unit-(SKU)-definition#SKUs_vs_products_0" style="color: rgb(248, 117, 81); text-decoration: none; display: block; height: 1px; padding-top: 120px; margin-top: -120px"><font color="rgb(248, 117, 81)">
</font></a>SKUs vs. products
</h2>
<font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">Unlike a <i style="color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">product</i>, a <b style="font-weight: 600; color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">SKU is bound to a particular location</b>. For example for a given product (ex: a book as identified by its ISBN barcode), a retail network can have as many SKUs as there are locations where the book can be stored; typically one SKU per store and per warehouse. <br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />It is also possible to have multiple SKUs for the same item within a single store. Even if the majority of the items are stored at a single location within the store, some items may be sold at several locations, hence generating extra SKUs.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />Also a product may have many variants based on attributes such as size, color or conditioning. Thus, even when considering a single location, a single product can be associated to multiple SKUs.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />SKUs matter because they represent the most fine-grained level, hence the <b style="font-weight: 600; color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">most desirable level for inventory optimization</b>.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /></font>
<h2 class="separator" style="margin-top: 0px; margin-bottom: 0; font-weight: 400; line-height: 1.2; font-size: 32px; color: rgb(248, 117, 81); font-family: Open Sans, Helvetica, Arial, sans-serif; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">
<a class="headeranchor" id="Stock_on_hand_1" href="https://www.lokad.com/stock-keeping-unit-(SKU)-definition#Stock_on_hand_1" style="color: rgb(248, 117, 81); text-decoration: none; display: block; height: 1px; padding-top: 120px; margin-top: -120px"><font color="rgb(248, 117, 81)">
</font></a>Stock on hand
</h2>
<font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">Each SKU is associated with its <b style="font-weight: 600; color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">stock on hand</b> which represents the number of units readily available for consumption (or picking) at the SKU location. The stock on order represents the amount of inventory in transit that is already due to replenish the SKU in the future. <br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />The vast majority of goods being sold nowadays are packaged lead to strictly integral values for the stock on hand. However, more traditional segments such as fruits or vegetables are still frequently sold by the weight.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />As units associated to a SKU are assumed indistinguishable, at any given time, <b style="font-weight: 600; color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">the state of an SKU is defined by its stock on hand value</b>. However, in practice, the stock on hand is not accounted for through direct measurements, at least not systematically. Indeed, only inventory <i style="color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">movements</i> are accounted for, and the measure of the stock on hand is typically inferred from the history of movements.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />The process of <b style="font-weight: 600; color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">inventorying</b> consists of performing direct inventory measurements, i.e. to count stock on hand values for SKUs. However, this process is intended as a </font><a class="pagelink" href="https://www.lokad.com/phantom-inventory-definition" title=" Phantom Inventory Definition" style="color: rgb(248, 117, 81); text-decoration: none; background-color: rgb(255, 255, 255); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px"><font color="rgb(248, 117, 81)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">correcting measure</font></a><font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px"> to improve the </font><a class="pagelink" href="https://www.lokad.com/inventory-accuracy-definition" title="Inventory Accuracy Definition" style="color: rgb(248, 117, 81); text-decoration: none; background-color: rgb(255, 255, 255); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px"><font color="rgb(248, 117, 81)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">inventory accuracy</font></a><font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">, and it is performed relatively infrequently because of the manpower costs involved.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /></font>
<h2 class="separator" style="margin-top: 0px; margin-bottom: 0; font-weight: 400; line-height: 1.2; font-size: 32px; color: rgb(248, 117, 81); font-family: Open Sans, Helvetica, Arial, sans-serif; font-style: normal; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">
<a class="headeranchor" id="Lokad_gotcha_2" href="https://www.lokad.com/stock-keeping-unit-(SKU)-definition#Lokad_gotcha_2" style="color: rgb(248, 117, 81); text-decoration: none; display: block; height: 1px; padding-top: 120px; margin-top: -120px"><font color="rgb(248, 117, 81)">
</font></a>Lokad gotcha
</h2>
<font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">Many <i style="color: rgb(33, 33, 34); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)">classic</i> inventory optimization methods poorly handle intermittent demand and low volume sales. However, as SKUs represent the most disaggregated inventory level, SKUs are typically strongly impacted by low volumes. As a result, those methods tend to shift the inventory analysis from the SKU level to the product level because the demand aggregated at the product level is stronger. Similarly, top-down approach where total demand is analyzed first before splitting the results down the hierarchy are also used to mitigate the limitation of classic methods when dealing with intermittent demand.<br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" /><br align="left" style="letter-spacing: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(255, 255, 255)" />Yet, we strongly advise not use such methods, because significant errors are typically introduced when the results are disaggregated back to the SKU levels. Modern methods such as </font><a class="pagelink" href="https://www.lokad.com/quantile-forecasting-technology" title="Quantile Forecasting Technology- Inventory Optimization Software" style="color: rgb(248, 117, 81); text-decoration: none; background-color: rgb(255, 255, 255); font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 17px; font-style: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px"><font color="rgb(248, 117, 81)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px">quantile forecasting</font></a><font color="rgb(33, 33, 34)" face="Open Sans, Helvetica, Arial, sans-serif" size="17px"> are well-suited to handle even the very low demand levels observed at the SKU level and should be used instead.</font>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1553775728770" ID="ID_756504666" MODIFIED="1553775743240" TEXT="存储">
<node CREATED="1553775745838" ID="ID_1524204948" MODIFIED="1553775767166">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
既然SKU是追踪库存的最小单位,那么这个最小单位可以是商品的某个规格,也可以是商品本身,而且对于简单商品(比如书,没有规格),库存的最小单元就是这个商品本身。
</p>
<p>
</p>
<ol>
<li>
对于简单商品,SKU=item_id + warehouse_id,所代表的意思是:追踪商品在给定位置的库存信息
</li>
<li>
对于多规格商品,SKU = item_id + item_variation_id + warehouse_id,所代表的意思是:追踪商品的具体规格在给定位置的库存信息
</li>
</ol>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1553774960274" ID="ID_1715252020" MODIFIED="1553774961530" TEXT="规格(Variation)">
<node CREATED="1553774963922" ID="ID_255766748" MODIFIED="1553774971943" TEXT="不用多说就是我们所理解的那个意思了,比如一件衣服有红色和白色两种规则"/>
</node>
<node CREATED="1553774983242" ID="ID_902626833" MODIFIED="1553774984372" TEXT="综上所述,商品规格和SKU是不同的内容,因此商品规格保存在独立的规格表中,SKU表属于库存,清单管理领域schema。"/>
</node>
<node CREATED="1553774999082" ID="ID_760233684" MODIFIED="1553775000357" TEXT="用户体系">
<node CREATED="1553775019282" ID="ID_582629642" MODIFIED="1553775026370" TEXT="简介">
<node CREATED="1553775028890" ID="ID_1057983020" MODIFIED="1553775099028">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
由于有很多种用户类型,比如最简单的划分是分为个人用户和企业用户,而每种类型的用户所需填写的资料是不同的,比如个人用户就没有营业执照,企业用户可能就不是用手机号码作为账号登录后台,在有些系统中这些用户都是存放在相同的表中,这个表的字段既包含了个人用户需要的字段,也包含了企业用户需要的字段,只是根据不同的用户类型,所填写的字段不一样,这其实很容易让数据混乱。不管是个人还是企业用户,他们都是用户,有【IS-A】的关系,比如:个人用户
</p>
<p>
【IS-A】用户,因此在这里,我们抽取一个主的用户表,表中字段是各种不同类型的用户共有的字段(即使就一个用户ID字段),然后不同类型的用户在各自所在的表中。这样做的好处有:
</p>
<p>
(1),每种不同类型的用户只需要处理自己所需的字段,数据清晰,业务逻辑清晰;
</p>
<p>
(2),由于有一个主的用户表,其他表,比如店铺表,商品表中的user_id字段的定义也就明确了,不会出现【如果xx,就代表是A用户】,【如果yy,就代表是B用户】的情况。
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1558100041187" ID="ID_1268710844" MODIFIED="1558100049995" TEXT="权限体系">
<node CREATED="1558096624603" ID="ID_1120110537" MODIFIED="1558096628582" TEXT="role">
<node CREATED="1558096631194" ID="ID_1554461704" MODIFIED="1558096658506" TEXT="父子关系不仅仅为了组织结构,也有继承关系">
<node CREATED="1558096668794" ID="ID_1445173526" MODIFIED="1558096725271" TEXT="子节点只能继承它【直接】父节点,不能跨级继承"/>
<node CREATED="1558096728075" ID="ID_1931098111" MODIFIED="1558096775209" TEXT="子节点的权限只能是它直接父节点的子集"/>
<node CREATED="1558096781618" ID="ID_221178286" MODIFIED="1558096831821" TEXT="子节点使用排除的方式,排除掉从父节点继承的权限"/>
<node CREATED="1576677351119" ID="ID_330904897" MODIFIED="1576677946268" TEXT="只继承直接父节点?那linux chmod -R 如何解释"/>
</node>
</node>
<node CREATED="1558315308389" ID="ID_1159422463" MODIFIED="1558316594781" TEXT="permission system">
<node CREATED="1558315008559" ID="ID_413431121" MODIFIED="1558315015099" TEXT="permission">
<node CREATED="1558315124457" ID="ID_678251735" MODIFIED="1576675109286" TEXT="只能唯一属于一个category"/>
</node>
<node CREATED="1558315350100" ID="ID_117868615" MODIFIED="1558315364330" TEXT="为什么这么设计?">
<node CREATED="1558315366908" ID="ID_140560390" MODIFIED="1558315592160" TEXT="方便处理包含关系"/>
<node CREATED="1558315391565" ID="ID_481137115" MODIFIED="1558315483746" TEXT="使用集合的概念,方便理解"/>
<node CREATED="1558315683574" ID="ID_1433513793" MODIFIED="1558315735970" TEXT="借鉴文件系统,程序包组织结构"/>
</node>
<node CREATED="1558315777654" ID="ID_1875858245" MODIFIED="1558315784132" TEXT="规则">
<node CREATED="1558315788728" ID="ID_933615020" MODIFIED="1558316328161" TEXT="使用集合的概念,即满足集合的操作规则 "/>
<node CREATED="1558316492392" ID="ID_568818890" MODIFIED="1576676495932" TEXT="用户的permission集合等于该用户自身拥有的permission与其他地方拥有的(比如所属角色拥有的)permission的【并集】">
<font NAME="SansSerif" SIZE="12"/>
</node>
<node CREATED="1558356310776" ID="ID_457302035" MODIFIED="1584534575407" TEXT="即使相同的subject和permission的关系出现多次,最终结果只保留一次,因为对于集合来说,同一个元素即使多次添加,也只会有一个这样的元素存在,在编程的时候维护好关系"/>
<node CREATED="1576675264042" ID="ID_823813655" MODIFIED="1576675325404" TEXT="【排除】的意义">
<node CREATED="1576675328015" ID="ID_200262369" MODIFIED="1576675903127" TEXT="可以做继承">
<node CREATED="1576675906136" ID="ID_854860185" MODIFIED="1576675907804" TEXT="有继承必然需要排除,比如从父账号继承了权限,但是可能其中某些权限不能给该用户,这样就可以使用【排除】"/>
</node>
<node CREATED="1576675507314" ID="ID_590316268" MODIFIED="1576675771092" TEXT="用户或者角色可以和permission category建立关系,即可以把整个permission category的权限分配给某个用户或者角色">
<node CREATED="1576675913200" ID="ID_1254681877" MODIFIED="1576675986916" TEXT="但是可能其中某些权限不能给该用户,这样就可以使用【排除】"/>
</node>
<node CREATED="1576676133190" ID="ID_708976398" MODIFIED="1576676237704" TEXT="当把很多个权限打包(一揽子)分配出去后,就一定会需要【排除】功能"/>
</node>
<node CREATED="1584534783815" ID="ID_1595500011" MODIFIED="1584534789076" TEXT="包含">
<node CREATED="1577605227249" ID="ID_1795633900" MODIFIED="1577605384024" TEXT="对于path的格式,比如:/*,表示对整个目录下的文件和目录都有给定的actions,因此做【包含】关系是在【作用的对象】这一层"/>
</node>
<node CREATED="1584534310568" ID="ID_449270997" MODIFIED="1584534329478" TEXT="白名单和黑名单">
<node CREATED="1558315832441" ID="ID_1688793760" MODIFIED="1584535373709" TEXT="如果既保存【拥有】的权限,又保存【拒绝】的权限,那么需要subject保存完整的权限,清楚的列出subject拥有哪些,没有哪些permission,即【拥有】+【拒绝】等于所有权限,不然,没有保存的,你就不知道到底是拥有还是拒绝呢?">
<node CREATED="1584535663110" ID="ID_158928824" MODIFIED="1584535727317" TEXT="因此该方式不可取,只保存【拥有】或者只保存【拒绝】,是更好的方式"/>
</node>
<node CREATED="1558315933519" ID="ID_1790964345" MODIFIED="1558316018645" TEXT="有的业务保存的是正面清单,即【选择】的项目,但是有些业务保存的负面清单,即【排除】项目">
<node CREATED="1584538271328" ID="ID_941300794" MODIFIED="1584538347361" TEXT="2020/2/20:subject和permission的关联关系表明确的认为是【拥有】关系"/>
<node CREATED="1584536104319" ID="ID_938295770" MODIFIED="1584538542388" TEXT="2020/3/18:subject与permission的关联关系表中,仅仅只保存了关联关系,不指明到底是【拥有】还是【拒绝】,而是由业务具体决定,但是只能是其中一种,即该业务全部使用【白名单】方式,或者全部使用【黑名单】方式"/>
</node>
</node>
</node>
<node CREATED="1584241054092" ID="ID_76230846" MODIFIED="1584241105552" TEXT="术语">
<node CREATED="1584241113554" ID="ID_1977527035" MODIFIED="1584241577169" TEXT="target">
<node CREATED="1584241397119" ID="ID_399961975" MODIFIED="1584241495703" TEXT="permission 作用的对象,比如用户对文件拥有read权限,在这里文件就是作用对象"/>
</node>
<node CREATED="1584241126504" ID="ID_764471657" MODIFIED="1584241130888" TEXT="action">
<node CREATED="1584241488120" ID="ID_549959219" MODIFIED="1584241527480" TEXT="对于文件来说,有read,write等action"/>
</node>
<node CREATED="1584241133376" ID="ID_219874969" MODIFIED="1584241138874" TEXT="subject">
<node CREATED="1584241150313" ID="ID_642781115" MODIFIED="1584241167945" TEXT="A subject may be any entity, such as a person or a service"/>
<node CREATED="1584241176800" ID="ID_1053049329" MODIFIED="1584241182921" TEXT="https://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/JAASRefGuide.html#Subject"/>
</node>
<node CREATED="1584241141400" ID="ID_1351047467" MODIFIED="1584241146732" TEXT="subject group">
<node CREATED="1584241188161" ID="ID_178076877" MODIFIED="1584241262656" TEXT="当subject是用户时,subject group 可能就是role"/>
</node>
<node CREATED="1584241706304" ID="ID_1498366554" MODIFIED="1584241711166" TEXT="permission">
<node CREATED="1584241630472" ID="ID_343656868" MODIFIED="1584538595282" TEXT="一个比较好的理解方式:一个subject(比如user)对于target(比如文件)有某些action(比如read)权限"/>
</node>
</node>
<node CREATED="1576676542768" ID="ID_179933648" MODIFIED="1576676551491" TEXT="可能的问题">
<node CREATED="1576676555327" ID="ID_1317009712" MODIFIED="1576676868812" TEXT="如果有【继承】,排除,一揽子分配权限等操作时,用户拥有的权限可能都搞不清从哪里来,也搞不清为什么就没有了">
<node CREATED="1576676673144" ID="ID_782525540" MODIFIED="1576676888100" TEXT="标记处每个权限的出处和为什么没有"/>
</node>
<node CREATED="1576676896199" ID="ID_213340959" MODIFIED="1576677203078" TEXT="如果用户拥有某个permission category时,表示用户拥有整个分类下的权限,如果权限A一开始在这个category中,后来又移动到其他category下了,那么就有种【我以前拥有的权限,怎么突然就没有了】"/>
</node>
<node CREATED="1576677447383" ID="ID_985561924" MODIFIED="1576677453115" TEXT="参考">
<node CREATED="1576677455895" ID="ID_1709068044" MODIFIED="1576677462932" TEXT="MySQL">
<node CREATED="1576677468991" ID="ID_1123152724" MODIFIED="1576677571029" TEXT="单个用户对应单个功能,没有继承,排除,分类等等,很清晰"/>
</node>
<node CREATED="1576677573775" ID="ID_1699259380" MODIFIED="1576677577667" TEXT="Linux">
<node CREATED="1576677580102" ID="ID_1349579496" MODIFIED="1576677594824" TEXT="chmod -r"/>
<node CREATED="1576677597408" ID="ID_38463187" MODIFIED="1576677708120" TEXT="用户可以对整个目录和下级目录(递归)分配权限,类比这里的permission category"/>
</node>
</node>
</node>
</node>
<node CREATED="1576508208743" ID="ID_836012638" MODIFIED="1576508227607" TEXT="子账号"/>
<node CREATED="1584019444835" ID="ID_1104496610" MODIFIED="1584019507223" TEXT="特别的规则">
<node CREATED="1584019455888" ID="ID_1031999827" MODIFIED="1584019677502" TEXT="账号的状态 account status">
<node CREATED="1584019588722" ID="ID_249548052" MODIFIED="1584019624977" TEXT="0:系统内建的一个状态值,业务不可使用,就好像系统保留的关键字一样,用于系统用户初始化"/>
</node>
<node CREATED="1584019641566" ID="ID_391715275" MODIFIED="1584019671776" TEXT="用户的状态 user status">
<node CREATED="1584019680925" ID="ID_1367685441" MODIFIED="1584019697410" TEXT="0:统内建的一个状态值,业务不可使用,就好像系统保留的关键字一样,用于系统用户初始化"/>
</node>
<node CREATED="1584019775977" ID="ID_85561686" MODIFIED="1584019783690" TEXT="用户的类型 user type">
<node CREATED="1584019786661" ID="ID_1735054511" MODIFIED="1584019828590" TEXT="0:统内建的一个状态值,业务不可使用,就好像系统保留的关键字一样,表示系统用户"/>
</node>
<node CREATED="1584020957245" ID="ID_1131201862" MODIFIED="1584020962722" TEXT="root用户">
<node CREATED="1584020965260" ID="ID_783692045" MODIFIED="1584021353490" TEXT="初始密码是:123456"/>
</node>
</node>
</node>
<node CREATED="1553775119834" FOLDED="true" ID="ID_1286617994" MODIFIED="1584019414388" TEXT="活动体系">
<node CREATED="1553775127418" ID="ID_503687606" MODIFIED="1553775138051">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
和用户体系类似,活动有很多种,而且不同活动的规则不一样,因此,每种活动必须分别保存到各自相应的表中,但是不同的活动总是活动,也有【IS-A】的关系,因此活动schema中有一个主的活动表。
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553775148330" ID="ID_681160803" MODIFIED="1586654923905" TEXT="商品">
<node CREATED="1553776301011" ID="ID_1738195634" MODIFIED="1553776305966" TEXT="商品类型">
<node CREATED="1553776232722" ID="ID_563172285" MODIFIED="1553776236948" TEXT="参考:https://learnwoo.com/woocommerce-different-product-types/"/>
<node CREATED="1553775203442" ID="ID_741802732" MODIFIED="1553776377611" TEXT="做法">
<node CREATED="1553775212650" ID="ID_832288797" MODIFIED="1553775232619">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
有这么多中商品类型,而且每种类型的模型完全不一样,因此,千万不能用一套表就想保存所有类型的商品,必须每种类型定义一套相应的表,不然又进入【如果xx,就这样处理,如果yy,就那样处理】的混乱中。但是由于也有【IS-A】关系,比Simple Product IS A Product,因此,所有商品都有一个主的商品表。
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553776817394" FOLDED="true" ID="ID_2983827" MODIFIED="1587782002559" TEXT="Simple Product">
<node CREATED="1587781981700" ID="ID_1208526616" MODIFIED="1587781994114">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>Simple Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
A simple product is the most common and easily-understandable product type in WooCommerce. A simple product is a unique, stand-alone, physical product that you may have to ship to the customer. To start with, you can create a simple product, assign a price & SKU for the product, and start selling them. eg: Books.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553776958722" FOLDED="true" ID="ID_547849948" MODIFIED="1587782042914" TEXT="Grouped Product">
<node CREATED="1587782032377" ID="ID_1251804436" MODIFIED="1587782038462">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>Grouped Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
A grouped product is a cluster of simple products clubbed together to form a single entity. The grouped product won’t have a price or a unique identifier of its own. The identity of the grouped product is created by a number of child products that have unique features of their own. As soon as you create a grouped product, you can add at least one child product to the grouped product. Your customers can purchase any of the child product from the grouped product individually as well. eg: A set of six glasses.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553776999730" FOLDED="true" ID="ID_242239165" MODIFIED="1587782078114" TEXT="Virtual Product">
<node CREATED="1587782061745" ID="ID_1223158607" MODIFIED="1587782073637">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>Virtual Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
A virtual product is simply defined as a product that is not a physical entity. For this reason, there is no need to ship such a product. Therefore defining and configuring a virtual product is a simple and straightforward process. You don’t have to bother about details such as product dimensions and weight, which are generally part of any other product settings. eg: You list a service (rendered in person) as a product on your store.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553777031049" FOLDED="true" ID="ID_1835461025" MODIFIED="1587782118610" TEXT="Downloadable Product">
<node CREATED="1587782107801" ID="ID_1109383803" MODIFIED="1587782113726">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>Downloadable Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
Similar to virtual products, downloadable products also don’t require shipping. They are available as a downloadable file with a specified path or URL. In most cases, there will be a limit on the number of downloads of such products. In a seemingly ironic way, WooCommerce allows setting shipping options for downloadable products. This is in fact to include the scenario where you want to send a packaged version (like a CD) of the product to the customer. If your product is only downloadable and has no physical version, you can mark it as a virtual product.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553777076242" FOLDED="true" ID="ID_1617685870" MODIFIED="1587782156138" TEXT="External Product">
<node CREATED="1587782147113" ID="ID_909689837" MODIFIED="1587782151070">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>External Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
There are cases where you list a product in your store, but you are not the actual seller of the product. Your customers who wish to purchase such products will be redirected to the URL that you specify in the product settings. There is no need for you to add any product-specific data on your store.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1553777108626" FOLDED="true" ID="ID_176904708" MODIFIED="1587782202082" TEXT="Variable Product">
<node CREATED="1587782193778" ID="ID_699914038" MODIFIED="1587782197698">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<h2 style="font-family: Roboto, sans-serif; color: rgb(17, 17, 17); font-weight: 400; margin-top: 30px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; font-size: 27px; line-height: 38px; font-style: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
<strong style="font-weight: bold"><b>Variable Product</b></strong>
</h2>
<p style="font-family: Roboto; font-size: 18px; line-height: 26px; margin-top: 0px; margin-bottom: 26px; font-style: normal; color: rgb(58, 58, 58); font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: rgb(254, 254, 254)">
This product type lets you add variations to the same product to create a complex, variable product. Each variation of the product has its own price, SKU, available stock, etc. eg: A shirt or t-shirt with different sizes and different colors.
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
<node CREATED="1553775246306" FOLDED="true" ID="ID_1998918486" MODIFIED="1584019416013" TEXT="价格体系">
<node CREATED="1553775252346" ID="ID_1650956895" MODIFIED="1553775343700">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
在实际应用中可能会有多种价格,比如商品级别的价格,规格级别的价格,活动价格,甚至有些商品在不同地区也有不同价格,这些价格必须遵循以下规则
</p>
<p>
  1)越是具体的价格,优先级越高;比如:规格级别的价格优先于商品级别的价格,活动价格优先于规格级别的价格,就好像MySql数据库选项的值,配置文件的值会覆盖全局默认值,而命令行上设置的值又会覆盖配置文件中相同选项的值
</p>
<p>
  2)业务相关的价格必须保存到相应的业务表中,决不允许保存在item_price和item_variation_price表
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1553775333282" ID="ID_1591219249" MODIFIED="1553775346459" TEXT="所有价格的单位都是分,使用INT类型"/>
</node>
<node CREATED="1553775369282" FOLDED="true" ID="ID_554814480" MODIFIED="1587819291269" TEXT="属性">
<node CREATED="1553775381762" ID="ID_416903064" MODIFIED="1586662401883" TEXT="2019:属性池: item.attribute_pair"/>
<node CREATED="1587781564842" FOLDED="true" ID="ID_499348889" MODIFIED="1587782495009" TEXT="属性定义的思考">
<node CREATED="1553775401634" ID="ID_1582116423" MODIFIED="1586655706674">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
2019:每个商家可以预定义属性, 但是所有商家实际是共同维护和分享属性池; 商家在添加时, 先把属性放入属性池中(如果没有), 然后用一个指针指向该属性; 修改时, 先新增一个属性(如果没有), 然后将指针指向新增加的这个属性, 旧的属性不受任何影响, 只是当前商家没有指向这个属性而已; 删除时, 将这个指针废弃掉即可.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1553775427690" ID="ID_1769414441" MODIFIED="1586655712116">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
2019:在添加商品时, 属性只能是模板作用, 即选择一个属性后, 应该将文本的属性名称和属性值固定保存, 不能使用ID去关联, 这是因为如果属性被修改, 使用ID关联的话, 所有关联该属性的商品都会受影响. 有些时候这是对的, 但有些时候又是不正确的, 为了避免这种不确定的影响, 不使用ID关联属性, 而是使用当时该属性的快照值.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1586662340910" ID="ID_616639044" MODIFIED="1586662348572" TEXT="2019:每个店铺可以预先定义商品属性, 在添加商品时, 就可以从这些预先定义的属性中选择, 不需要每次添加商品时都新建. 如果每个商家都独享属性,那么属性会重复出现, 比如有一百个商家卖衣服, 那么Color属性会出现至少一百次, 因此为了不必要的重复, 所有商家共同维护一个属性池, 每个商家的属性只是指向这个属性池中的特定的属性. 举例: Color属性在属性池中只有一个, 商家A和商家B的Color属性都是指向属性池中的那个Color. 在这里所谓的属性池就是item.attribute_pair表. 因此商家添加的属性, 首先进入属性池中, 然后再用一个指针指向刚刚添加的这个属性. 而商家在修改属性时, 先添加一个新的属性, 将原来的指针指向这个新的属性, 以前旧的那个属性并不会被修改, 因为其他商家可能还在使用这个属性, 不能影响其他商家. 而且这些数据都是非常珍贵的, 积少成多. "/>
<node CREATED="1586655789973" ID="ID_264283841" MODIFIED="1586662380275">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
2020/4/12
</p>
<p>
</p>
<p>
1,mount point ,属性挂载点,由于同一类商品,具有的属性是相似的,因此属性挂载到分类上很合适,在一个分类下新建商品时,可以方便的从分类上筛选挂载到它上面的属性,然后添加到商品上。但是属性也 不一定挂载到分类上,这要看具体业务,因此使用挂载点这样的比较抽象的定义,方便业务扩展。  
</p>
<p>
</p>
<p>
2,mount point identifier : 属性挂载点的唯一标记,比如:商品分类ID   
</p>
<p>
3,mount point type :属性挂载点的类型,比如:商品分类    
</p>
<p>
</p>
<p>
4,同一个名称和值,适应于多个目标,比如:属性名是颜色,属性值是白色,很多店铺可能都有这个属性,卖电脑的商家有颜色是白色的电脑,卖衣服的商家有颜色是白色的衣服,而且同一个店铺下,不同类型的商品也需要这个属性,比如在一个卖电子产品的店铺内,有白色的电视,也有白色的手机,所以让人很容易往共享属性,设计通用的属性这个方向思考,因此:
</p>
<ul>
<li>
可以在不同商家或者用户之间共享吗?
</li>
<li>
如果不同商家之间不能共享,那么同一个商家内,不同挂载点(比如分类)之间可以共享吗?     
</li>
</ul>
<p>
5,共享和不共享引出的问题
</p>
<ul>
<li>
如果不共享,则数据库中有很多这种相同名称和值的数据,总感觉浪费存储   
</li>
<li>
如果共享,如何解决变更等问题,比如【颜色:白色】这个属性对,商家A觉得不好,改成了【颜色:纯白色】,这时候商家B突然发现没有【颜色:白色】这个属性对没有了    
</li>
<li>
如果共享,会影响隐私吗?比如商家A建立了一个属性对,商家B也可以使用  
</li>
</ul>
<p>
  
</p>
<p>
6,如果是商品,你会毫不犹豫的加上店铺ID,表明商品就是属于某个店铺,但是商品属性,总感觉可以使用通用的属性实体,总感觉可以共享,所以总是试图把Attribute设计成通用的,但是商品属性不适合使用通用的设计,因为它有自己很强的业务规则,在JDK中搜索Attribute相关的内容,发现每种场景也是有自己的Attribute,而不是通用的。因此,商品的属性还是【不共享】。
</p>
<p>
</p>
<p>
7,店铺之间不共享,表的设计如下:
</p>
<p>
</p>
<p>
CREATE TABLE IF NOT EXISTS `commons`.`item_attribute_definition` (
</p>
<p>
  `attribute_name_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `store_id` BIGINT UNSIGNED NOT NULL COMMENT '所属店铺的ID',
</p>
<p>
  `attribute_name` VARCHAR(45) NOT NULL COMMENT '属性名',
</p>
<p>
  `attribute_value` JSON NOT NULL COMMENT '属性值',
</p>
<p>
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
</p>
<p>
  `create_user_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `last_modify_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
</p>
<p>
  `last_modify_user_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `is_deleted` BIGINT UNSIGNED NOT NULL DEFAULT 0,
</p>
<p>
  PRIMARY KEY (`attribute_name_id`),
</p>
<p>
  INDEX `fk_store_id` (`store_id` ASC) VISIBLE,
</p>
<p>
  CONSTRAINT `fk_store_id`
</p>
<p>
    FOREIGN KEY (`store_id`)
</p>
<p>
    REFERENCES `store`.`store` (`store_id`)
</p>
<p>
    ON DELETE NO ACTION
</p>
<p>
    ON UPDATE NO ACTION)
</p>
<p>
COMMENT = '属性名称, 比如颜色, 规格'。
</p>
<p>
</p>
<p>
店铺之间不共享,是很合理的,但是店铺内可以共享吗?属性只属于这个店铺,不挂载到分类上呢?这个就不好说了,只能看具体业务,因此,一开始不设置属性的挂载点,而是使用属性与挂载点的关联关系表表示,这样可以处理这几种需求:
</p>
<ul>
<li>
如果属性不需要挂载,是店铺层面的,那么这个表中也就是没记录
</li>
<li>
如果是店铺内不共享属性,那么由程序做校验处理,而不在表中设置唯一键来约束
</li>
<li>
如果是可以共享,那么这个表本身就可以多对多
</li>
</ul>
<p>
</p>
<p>
CREATE TABLE IF NOT EXISTS `commons`.`item_attribute_definition` (
</p>
<p>
  `attribute_name_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `store_id` BIGINT UNSIGNED NOT NULL COMMENT '所属店铺的ID',
</p>
<p>
  `attribute_name` VARCHAR(45) NOT NULL COMMENT '属性名',
</p>
<p>
  `attribute_value` JSON NOT NULL COMMENT '属性值',
</p>
<p>
  `mount_point_identifier` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '挂载点唯一标记,0表示没有挂载',
</p>
<p>
  `mount_point_type` TINYINT UNSIGNED NOT NULL DEFAULT 0,
</p>
<p>
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
</p>
<p>
  `create_user_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `last_modify_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
</p>
<p>
  `last_modify_user_id` BIGINT UNSIGNED NOT NULL,
</p>
<p>
  `is_deleted` BIGINT UNSIGNED NOT NULL DEFAULT 0,
</p>
<p>
  PRIMARY KEY (`attribute_name_id`),
</p>
<p>
  INDEX `fk_store_id` (`store_id` ASC) VISIBLE,
</p>
<p>
  CONSTRAINT `fk_store_id`
</p>
<p>
    FOREIGN KEY (`store_id`)
</p>
<p>
    REFERENCES `store`.`store` (`store_id`)
</p>
<p>
    ON DELETE NO ACTION
</p>
<p>
    ON UPDATE NO ACTION)
</p>
<p>
COMMENT = '属性名称, 比如颜色, 规格';
</p>
<p>
</p>
<p>
我们的想法是一个店铺下虽然有多个【颜色:白色】这样的属性,但是因为他们挂载到不同地方,因此也是不同的数据,但是如果一开始不挂载呢?如果有需求是在店铺层面上建立和管理属性,不需要再细分,但是随着业务的变化,根本不需要挂载到其他对方,比如分类。但是现在不挂载,所以把挂载点相关的信息放进来也是没用,除非是属性创建时一开始就指定了挂载点,这好像也不合理,店铺之间不共享很容易解决,加上store_id即可,但是店铺内不共享,却比较难处理
</p>
<p>
</p>
<p>
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1587781469024" ID="ID_1941878754" MODIFIED="1587782502220" TEXT="商品的属性">
<node CREATED="1587708576162" ID="ID_1708354533" MODIFIED="1587712118549" TEXT="保存属性ID还是保存纯文本的属性名称和属性值呢?">
<node CREATED="1587710243836" ID="ID_14148773" MODIFIED="1587712133318" TEXT="保存纯文本的属性名称和属性值">
<node CREATED="1587782534489" ID="ID_952413235" MODIFIED="1587782649742">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
表设计伪代码:
</p>
<table border="0" style="width: 80%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 0; border-right-width: 0; border-bottom-width: 0; border-left-width: 0">
<tr>
<td valign="top" style="width: 33%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
item_id
</p>
</td>
<td valign="top" style="width: 33%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_name
</p>
</td>
<td valign="top" style="width: 33%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_value
</p>
</td>
</tr>
</table>
</body>
</html></richcontent>
</node>
<node CREATED="1587712336475" ID="ID_1684881974" MODIFIED="1587712655179" TEXT="好比是静态编译,商品使用属性后,把这个属性当时的名称和值静态保存起来,后续如果属性名和值变化了,该商品都不再能感知到"/>
<node CREATED="1587712669698" ID="ID_1307826691" MODIFIED="1587712677267" TEXT="优点">
<node CREATED="1587712681099" ID="ID_560279159" MODIFIED="1587712786072" TEXT="当属性实体本身被修改后,不会影响其他商品"/>
<node CREATED="1587712820404" ID="ID_445539555" MODIFIED="1587712846235" TEXT="修改某个商品的属性时,完全不会影响属性实体本身,也不会影响其他商品"/>
</node>
<node CREATED="1587712851612" ID="ID_1098733027" MODIFIED="1587712855435" TEXT="缺点">
<node CREATED="1587712950878" ID="ID_781951711" MODIFIED="1587713140248" TEXT="失去了属性实体本身的信息,导致对该属性操作时,没有了该属性的元数据信息">
<node CREATED="1587713142991" ID="ID_1535350716" MODIFIED="1587714208609" TEXT="举例:颜色这个属性,很多应用都可以使用调色盘取颜色,或者在显示时直接显示颜色,而不是【白色,红色】这样的文本,这是因为,程序查询到这个属性的基本信息后,知道这是一个特殊的属性,然后调出调色盘,但是现在只是保存【颜色,color】这样的纯文本属性名,程序也只会把它当作一个普通的属性名"/>
<node CREATED="1587713438144" ID="ID_567162607" MODIFIED="1587714363284" TEXT="如果修改一个商品的属性时,不能给出一些提示和约束,比如【城市】这个属性,现在只是保存了属性名,在修改时,程序再也不能给出下拉列表提示有哪些城市了,也无法阻止用户输入【鲨鱼】这样的属性值,虽然【鲨鱼】根本不属于城市,但是由于没有了属性实体本身的信息,程序是完全处理不了的"/>
</node>
</node>
</node>
<node CREATED="1587712137791" ID="ID_1900850350" MODIFIED="1587712176385" TEXT="保存属性ID">
<node CREATED="1587782661986" ID="ID_1035337380" MODIFIED="1587782692820">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
表设计伪代码:
</p>
<table border="0" style="width: 80%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 0; border-right-width: 0; border-bottom-width: 0; border-left-width: 0">
<tr>
<td valign="top" style="width: 50%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
item_id
</p>
</td>
<td valign="top" style="width: 50%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_id
</p>
</td>
</tr>
</table>
</body>
</html></richcontent>
</node>
<node CREATED="1587712203752" ID="ID_1480486939" MODIFIED="1587712569241" TEXT="好比是动态编译,被引用的属性修改后,该商品也能使用到最新的修改后的内容"/>
<node CREATED="1587715234946" ID="ID_130311322" MODIFIED="1587715241077" TEXT="缺点">
<node CREATED="1587716328803" ID="ID_331816243" MODIFIED="1587716663654" TEXT="如果商品不从全局的属性实体中选择,而是定义只属于这个商品的属性,如果只保存key-value,很方便,如果转换成属性实体,那就很麻烦了"/>
<node CREATED="1587712234183" ID="ID_96223354" MODIFIED="1587712596201" TEXT="如果某个商品不适合修改后的内容呢?"/>
<node CREATED="1587712603871" ID="ID_770424627" MODIFIED="1587715286803" TEXT="什么时候被谁修改了都不知道"/>
</node>
</node>
<node CREATED="1587718586322" ID="ID_634080335" MODIFIED="1587718610555" TEXT="既保存属性ID,又保存属性名称和值">
<node CREATED="1587782702970" ID="ID_1363607450" MODIFIED="1587783025832">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
表设计伪代码:
</p>
<table border="0" style="width: 80%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 0; border-right-width: 0; border-bottom-width: 0; border-left-width: 0">
<tr>
<td valign="top" style="width: 25%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
item_id
</p>
</td>
<td valign="top" style="width: 25%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_id
</p>
</td>
<td valign="top" style="width: 25%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_name
</p>
</td>
<td valign="top" style="width: 25%; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1; border-right-width: 1; border-bottom-width: 1; border-left-width: 1">
<p style="margin-top: 1; margin-right: 1; margin-bottom: 1; margin-left: 1">
attribute_value
</p>
</td>
</tr>
</table>
</body>
</html></richcontent>
</node>
<node CREATED="1587718618071" ID="ID_13764693" MODIFIED="1587718631085" TEXT="优点">
<node CREATED="1587718639099" ID="ID_524527769" MODIFIED="1587718653594" TEXT="静态,动态内容都能感知到"/>
</node>
<node CREATED="1587718632889" ID="ID_1365145004" MODIFIED="1587718636338" TEXT="缺点">
<node CREATED="1587719832518" ID="ID_868502410" MODIFIED="1587720344452" TEXT="程序员看到这样的数据,一定会搞出很多if else和曲线救国的玩法"/>
<node CREATED="1587720348644" ID="ID_1103221657" MODIFIED="1587721173468" TEXT="如果某个商品修改属性时,把保存的纯文本属性名被修改了,那么引用的属性ID也没有了意义,因为属性名已经对不上了,同样的,如果属性实体本身修改了属性名,那么这个商品保存的纯文本属性名也和属性ID指向的那个属性实体的名称对不上"/>
</node>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1553774749594" ID="ID_643540840" MODIFIED="1553774766307" POSITION="right" TEXT="约定">
<node CREATED="1553776464706" ID="ID_1167871489" MODIFIED="1553776468809" TEXT="索引">
<node CREATED="1553776473442" ID="ID_1117480713" MODIFIED="1553776541990" TEXT="外键索引名称以【fk_】开头"/>
<node CREATED="1553776506938" ID="ID_1141640017" MODIFIED="1553776522996" TEXT="索引名称以【idx_】开头"/>
</node>
<node CREATED="1553776575946" ID="ID_49826418" MODIFIED="1553776583996" TEXT="公共字段">
<node CREATED="1553776591578" ID="ID_1312796628" MODIFIED="1576502535299" TEXT="ID字段">
<node CREATED="1571750956717" ID="ID_320899835" MODIFIED="1571750965504" TEXT="取值定义">
<node CREATED="1553774857522" ID="ID_345744950" MODIFIED="1553774858632" TEXT="由于is_deleted机制,所有表的ID字段都不能等于0,因为is_deleted默认等于0"/>
<node CREATED="1585057821838" ID="ID_1440639917" MODIFIED="1585057937788" TEXT="ID不等于0,就可以使用primitive data type"/>
<node CREATED="1571750566327" ID="ID_547230877" MODIFIED="1571750728300" TEXT="预留【1~100】,以便一些特殊数据"/>
<node CREATED="1576504532702" ID="ID_79398714" MODIFIED="1576504579571" TEXT="由于parent_id的机制,所有表的ID字段不能为0"/>
<node CREATED="1583328728523" ID="ID_539749446" MODIFIED="1583328820731" TEXT="所有表的ID字段都不能等于0,如果其他表的外键等于0,表示没有关联到任何数据"/>
</node>
<node CREATED="1571750973268" ID="ID_1372356133" MODIFIED="1571750980809" TEXT="命名定义">
<node CREATED="1576502300547" ID="ID_1312035177" MODIFIED="1576502483794" TEXT="非关系表,使用【表名_id】这样的格式">
<node CREATED="1576502495599" ID="ID_276314755" MODIFIED="1576502992208" TEXT="比如:item表,ID字段的名称是【item_id】"/>
<node CREATED="1571751380589" ID="ID_223191075" MODIFIED="1571751381721" TEXT="https://stackoverflow.com/questions/208580/naming-of-id-columns-in-database-tables"/>
</node>
<node CREATED="1576502541200" ID="ID_1454839459" MODIFIED="1576502562068" TEXT="关系表,字段名称就是【id】">
<node CREATED="1576502564875" ID="ID_970884403" MODIFIED="1576502657609" TEXT="比如:用户与角色的关系表是user_role_relationship,该表的ID字段的名称就是【id】"/>
</node>
</node>
</node>
<node CREATED="1553776630786" ID="ID_1213504434" MODIFIED="1584102900566" TEXT="create_time:创建时间,数据新增生成,以后都不允许修改"/>
<node CREATED="1553776641570" ID="ID_1052661131" MODIFIED="1584102897960" TEXT="create_user_id:创建人user ID,数据新增生成,以后都不允许修改"/>
<node CREATED="1553776659506" ID="ID_698955700" MODIFIED="1553776690318" TEXT="last_modify_time:最后一次修改时间">
<node CREATED="1576504463117" ID="ID_598769713" MODIFIED="1576504490304" TEXT="关联关系表可以不需要该字段"/>
</node>
<node CREATED="1553776673386" ID="ID_288187405" MODIFIED="1576502693559" TEXT="last_modify_user_id:最后一次修改者user ID">
<node CREATED="1576504494405" ID="ID_1143987511" MODIFIED="1576504495749" TEXT="关联关系表可以不需要该字段"/>
</node>
<node CREATED="1553776680906" ID="ID_216375592" MODIFIED="1553776740262" TEXT="is_deleted:是否已经逻辑删除,默认0,当值等于当前记录ID时表示已经逻辑删除">
<node CREATED="1553774785370" ID="ID_1775248935" MODIFIED="1553774828988">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
系统中的删除功能都是逻辑删除,但是逻辑删除会带来唯一约束问题。比如电话号码有唯一约束,当号码被一个用户删除后,其他用户又准备添加该号码,此时将会遇到不满足唯一约束问题。对于这样的问,一种解决方式是:需要唯一约束的字段和is_deleted共同组成唯一索引,默认情况下is_deleted等于0,表示没有逻辑除只有当【is_deleted等于当前记录的ID】时,表示该记录已经逻辑删除。这样的话处于正常,未删除状态下的记录总是只有一条,但是处于逻辑删除状态下的可以有条。举例:手机号码+is_deleted组成唯一索引,手机号码等于168,正常状态下(is_delete=0)的只有一条,但是逻辑删除的记录可以有多条,比如手机号码等于168,is_deleted等于1,2,3,4......
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1571840977065" ID="ID_667926848" MODIFIED="1571840980084" TEXT="https://english.stackexchange.com/questions/16161/one-who-creates-is-a-creator-what-is-one-who-updates"/>
</node>
<node CREATED="1557752459522" ID="ID_807299482" MODIFIED="1557752463877" TEXT="parent_id">
<node CREATED="1557752467115" ID="ID_1881472659" MODIFIED="1557752495876" TEXT="所有具有上下级关系,表示父级的字段都使用该名称"/>
<node CREATED="1557752498228" ID="ID_1019858583" MODIFIED="1557752506507" TEXT="默认等于0"/>
<node CREATED="1557752509698" ID="ID_778690808" MODIFIED="1557752602165" TEXT="值等于0表示已经是最上级"/>
</node>
<node CREATED="1589898654942" ID="ID_1627229215" MODIFIED="1589898659441" TEXT="状态">
<node CREATED="1589898709076" ID="ID_1644923864" MODIFIED="1589898723149" TEXT="status vs state">
<node CREATED="1589898726133" ID="ID_491910082" MODIFIED="1589898729415" TEXT="https://english.stackexchange.com/questions/12958/status-vs-state"/>
</node>
<node CREATED="1577597528344" ID="ID_1444327735" MODIFIED="1577716498223" TEXT="status">
<node CREATED="1577597549714" ID="ID_245201156" MODIFIED="1589898828730" TEXT="(进展的)状况,情形,是一个动态的“阶段”的感觉 "/>
</node>
<node CREATED="1589898742453" ID="ID_1952489973" MODIFIED="1589898746193" TEXT="state">
<node CREATED="1589899348533" ID="ID_780275602" MODIFIED="1589899390148" TEXT="the mental, emotional or physical condition that a person or thing is in"/>
<node CREATED="1589899320247" ID="ID_1933917833" MODIFIED="1589899345299" TEXT="What sort of state is X in?"/>
</node>
<node CREATED="1588948113583" ID="ID_153203144" MODIFIED="1589899452799" TEXT="有时候不好直接设计成state,因为有可能会有xx_state这样的细分"/>
</node>
<node CREATED="1577597537681" ID="ID_1785115406" MODIFIED="1577716528456" TEXT="type">
<node CREATED="1577597567600" ID="ID_1089682916" MODIFIED="1577716546406" TEXT="类型"/>
</node>
<node CREATED="1577718367153" ID="ID_1656200300" MODIFIED="1577718368569" TEXT="active"/>
<node CREATED="1577854089901" ID="ID_1524895364" MODIFIED="1577854093457" TEXT="name"/>
<node CREATED="1577854148394" ID="ID_1764311709" MODIFIED="1577854154718" TEXT="description"/>
<node CREATED="1557753552553" ID="ID_1604676920" MODIFIED="1571751476662" TEXT="relationship后缀">
<node CREATED="1557753575530" ID="ID_292827055" MODIFIED="1557753633885" TEXT="以该后缀结尾的表名,表示两个表具有多对多关联关系"/>
</node>
<node CREATED="1558342973535" ID="ID_921782173" MODIFIED="1558342983298" TEXT="column注释">
<node CREATED="1558342987832" ID="ID_14965369" MODIFIED="1558344202259" TEXT="不使用enum和set,使用其他方式代表枚举意义">
<node CREATED="1558343117711" ID="ID_1217736230" MODIFIED="1558343120134" TEXT="类似于status这样的列,通常我们是设计成tinyint,然后指定1代表xx,2代表yy等等"/>
<node CREATED="1558343184855" ID="ID_41704750" MODIFIED="1558343204573" TEXT="按照一定规则写注释,方便代码生成">
<node CREATED="1558343210943" ID="ID_1919218235" MODIFIED="1558344345027" TEXT="enum.ONE(1->xx);TWO(2->yy)"/>
<node CREATED="1558343363222" ID="ID_863307291" MODIFIED="1558344286702" TEXT="以【enum开头】,接着是一个【英文句号】,然后就是元素列表,元素之间用【英文分号】分隔"/>
<node CREATED="1558343622390" ID="ID_866932592" MODIFIED="1558344084845" TEXT="元素由一个【名称】开头,必须是【英文字母】,然后是一对【英文圆括号】,括号中是key-value pair,其中key就是该列的值,value是对应的描述,key和value之间用【英文->】符号分隔"/>
<node CREATED="1558348123190" ID="ID_1478771935" MODIFIED="1558348233616" TEXT="元素的key和value中都不允许出现【英文园括号】,以免和外部的【英文圆括号】混淆,不方便解析"/>
</node>
</node>
</node>
<node CREATED="1585144239811" ID="ID_755751557" MODIFIED="1585144287167" TEXT="对于type,name,status等字段,是否加上表(实体)前缀?">
<node CREATED="1585144290410" ID="ID_626795663" MODIFIED="1585144343997" TEXT="比如item表,类型的列,到底是用type还是item_type呢?">
<node CREATED="1585144346835" ID="ID_152460096" MODIFIED="1585144384781" TEXT="用type,因为表名已经有了命名空间,item.type也很自然"/>
<node CREATED="1585144393098" ID="ID_359644125" MODIFIED="1585144501139" TEXT="用item_type,虽然item.item_type不自然,但是有个很大的好处,那就是如果连表查询时,两个表都有个type字段,如果加上了表前缀,则天然的区分开了字段,而不需要取别名"/>
</node>
<node CREATED="1585144688417" ID="ID_765190691" MODIFIED="1585144783384" TEXT="最终还是决定不需要前缀,因为在很多orm框架中,如果使用动态sql,基本上都需要代码生成表,列的信息,可以在生成的代码中为列取别名,这个时候加上表前缀"/>
</node>
</node>
<node CREATED="1587819314699" ID="ID_1668084872" MODIFIED="1587819318963" POSITION="right" TEXT="treeable"/>
<node CREATED="1584170295782" FOLDED="true" ID="ID_617916247" MODIFIED="1587819296888" POSITION="left" TEXT="设计模式">
<node CREATED="1584170350686" ID="ID_1943455138" MODIFIED="1584170363377" TEXT="entity CRUD state">
<node CREATED="1584170307918" ID="ID_1495309601" MODIFIED="1584170900393" TEXT="由于我们的系统是面向数据库存储的,在实际应用中,同一个实体类在CRUD四种操作中都用于传参,比如User类,新增用户,更新用户,查询用户信息,可能都是使用User这个类,一个很重要的问题是每种操作,该为User对象设置哪些属性值呢?因此我们使用builder pattern创建实体类的实例,首先指定该实体类的实例是用于CRUD的哪种操作,然后在build方法中根据不同的操作做参数检查"/>
<node CREATED="1584170909540" ID="ID_1104797586" MODIFIED="1584170932453" TEXT="https://www.entityframeworktutorial.net/crud-operation-in-connected-scenario-entity-framework.aspx"/>
<node CREATED="1584170946341" ID="ID_884401333" MODIFIED="1584170947348" TEXT="https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state"/>
</node>
<node CREATED="1584970662462" ID="ID_829925597" MODIFIED="1584972392775" TEXT="查询单独处理">
<node CREATED="1584972021730" ID="ID_1504475533" MODIFIED="1584972304639" TEXT="因为查询比较偏具体业务,很多都是业务时才知道,而且业务变化很快"/>
<node CREATED="1584972085515" ID="ID_1616452107" MODIFIED="1584972352310" TEXT="不好统一定义接口,比如如何定义查询条件呢?自己写condition接口?基本上不太可能,而且有很多变种(比如对于单表查询,每种业务返回的字段不同,就是很多种不同的查询了)"/>
<node CREATED="1584972409937" ID="ID_1694838254" MODIFIED="1584972487303" TEXT="最好在具体业务中将数据查询动态化(注意不是if else拼接sql),而不是固定写一个方法,因为这个方法基本上是不通用的,不如用java形式写sql,写到具体业务中容易维护"/>
<node CREATED="1584972492985" ID="ID_683217477" MODIFIED="1584972586677" TEXT="data source类型太多,比如有RDBMS,有nosql,即使使用sql,不同数据库之间也有差异,因此享有统一定义接口,很难实现"/>
<node CREATED="1584972607851" ID="ID_1526552061" MODIFIED="1584972677712" TEXT="增,删,改相比查询就更好统一定义了"/>
</node>
</node>
</node>
</map>