*:first-child {
margin-top: 0 !important;
}

.markdown-body>*:last-child {
margin-bottom: 0 !important;
}

.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}

.markdown-body .anchor {
float: left;
padding-right: 4px;
margin-left: -20px;
line-height: 1;
}

.markdown-body .anchor:focus {
outline: none;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
margin-top: 0;
margin-bottom: 16px;
}

.markdown-body hr {
height: 0.25em;
padding: 0;
margin: 24px 0;
background-color: #e1e4e8;
border: 0;
}

.markdown-body blockquote {
padding: 0 1em;
color: #6a737d;
border-left: 0.25em solid #dfe2e5;
}

.markdown-body blockquote>:first-child {
margin-top: 0;
}

.markdown-body blockquote>:last-child {
margin-bottom: 0;
}

.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #c6cbd1;
border-bottom-color: #959da5;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #959da5;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}

.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #1b1f23;
vertical-align: middle;
visibility: hidden;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}

.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}

.markdown-body h1 {
padding-bottom: 0.3em;
font-size: 2em;
border-bottom: 1px solid #eaecef;
}

.markdown-body h2 {
padding-bottom: 0.3em;
font-size: 1.5em;
border-bottom: 1px solid #eaecef;
}

.markdown-body h3 {
font-size: 1.25em;
}

.markdown-body h4 {
font-size: 1em;
}

.markdown-body h5 {
font-size: 0.875em;
}

.markdown-body h6 {
font-size: 0.85em;
color: #6a737d;
}

.markdown-body ul,
.markdown-body ol {
padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}

.markdown-body li {
word-wrap: break-all;
}

.markdown-body li>p {
margin-top: 16px;
}

.markdown-body li+li {
margin-top: 0.25em;
}

.markdown-body dl {
padding: 0;
}

.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: 600;
}

.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}

.markdown-body table {
display: block;
width: 100%;
overflow: auto;
}

.markdown-body table th {
font-weight: 600;
}

.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid #dfe2e5;
}

.markdown-body table tr {
background-color: #fff;
border-top: 1px solid #c6cbd1;
}

.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}

.markdown-body img {
max-width: 100%;
box-sizing: content-box;
background-color: #fff;
}

.markdown-body img[align=right] {
padding-left: 20px;
}

.markdown-body img[align=left] {
padding-right: 20px;
}

.markdown-body code {
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
background-color: rgba(27,31,35,0.05);
border-radius: 3px;
}

.markdown-body pre {
word-wrap: normal;
}

.markdown-body pre>code {
padding: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}

.markdown-body .highlight {
margin-bottom: 16px;
}

.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}

.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 3px;
}

.markdown-body pre code {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}

.markdown-body .full-commit .btn-outline:not(:disabled):hover {
color: #005cc5;
border-color: #005cc5;
}

.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #d1d5da;
border-bottom-color: #c6cbd1;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #c6cbd1;
}

.markdown-body :checked+.radio-label {
position: relative;
z-index: 1;
border-color: #0366d6;
}

.markdown-body .task-list-item {
list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
margin-top: 3px;
}

.markdown-body .task-list-item input {
margin: 0 0.2em 0.25em -1.6em;
vertical-align: middle;
}

.markdown-body hr {
border-bottom-color: #eee;
}

/*

github.com style (c) Vasily Polovnyov

*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}

.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}

.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}

.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}

.hljs-string,
.hljs-doctag {
color: #d14;
}

.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}

.hljs-subst {
font-weight: normal;
}

.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}

.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}

.hljs-regexp,
.hljs-link {
color: #009926;
}

.hljs-symbol,
.hljs-bullet {
color: #990073;
}

.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}

.hljs-meta {
color: #999;
font-weight: bold;
}

.hljs-deletion {
background: #fdd;
}

.hljs-addition {
background: #dfd;
}

.hljs-emphasis {
font-style: italic;
}

.hljs-strong {
font-weight: bold;
}

/* Flowchart variables */
/* Sequence Diagram variables */
/* Gantt chart variables */
.mermaid .label {
color: #333;
}
.node rect,
.node circle,
.node ellipse,
.node polygon {
fill: #ECECFF;
stroke: #CCCCFF;
stroke-width: 1px;
}
.edgePath .path {
stroke: #333333;
}
.edgeLabel {
background-color: #e8e8e8;
}
.cluster rect {
fill: #ffffde !important;
rx: 4 !important;
stroke: #aaaa33 !important;
stroke-width: 1px !important;
}
.cluster text {
fill: #333;
}
.actor {
stroke: #CCCCFF;
fill: #ECECFF;
}
text.actor {
fill: black;
stroke: none;
}
.actor-line {
stroke: grey;
}
.messageLine0 {
stroke-width: 1.5;
stroke-dasharray: "2 2";
marker-end: "url(#arrowhead)";
stroke: #333;
}
.messageLine1 {
stroke-width: 1.5;
stroke-dasharray: "2 2";
stroke: #333;
}
#arrowhead {
fill: #333;
}
#crosshead path {
fill: #333 !important;
stroke: #333 !important;
}
.messageText {
fill: #333;
stroke: none;
}
.labelBox {
stroke: #CCCCFF;
fill: #ECECFF;
}
.labelText {
fill: black;
stroke: none;
}
.loopText {
fill: black;
stroke: none;
}
.loopLine {
stroke-width: 2;
stroke-dasharray: "2 2";
marker-end: "url(#arrowhead)";
stroke: #CCCCFF;
}
.note {
stroke: #aaaa33;
fill: #fff5ad;
}
.noteText {
fill: black;
stroke: none;
font-family: 'trebuchet ms', verdana, arial;
font-size: 14px;
}
/** Section styling */
.section {
stroke: none;
opacity: 0.2;
}
.section0 {
fill: rgba(102, 102, 255, 0.49);
}
.section2 {
fill: #fff400;
}
.section1,
.section3 {
fill: white;
opacity: 0.2;
}
.sectionTitle0 {
fill: #333;
}
.sectionTitle1 {
fill: #333;
}
.sectionTitle2 {
fill: #333;
}
.sectionTitle3 {
fill: #333;
}
.sectionTitle {
text-anchor: start;
font-size: 11px;
text-height: 14px;
}
/* Grid and axis */
.grid .tick {
stroke: lightgrey;
opacity: 0.3;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
/* Today line */
.today {
fill: none;
stroke: red;
stroke-width: 2px;
}
/* Task styling */
/* Default task */
.task {
stroke-width: 2;
}
.taskText {
text-anchor: middle;
font-size: 11px;
}
.taskTextOutsideRight {
fill: black;
text-anchor: start;
font-size: 11px;
}
.taskTextOutsideLeft {
fill: black;
text-anchor: end;
font-size: 11px;
}
/* Specific task settings for the sections*/
.taskText0,
.taskText1,
.taskText2,
.taskText3 {
fill: white;
}
.task0,
.task1,
.task2,
.task3 {
fill: #8a90dd;
stroke: #534fbc;
}
.taskTextOutside0,
.taskTextOutside2 {
fill: black;
}
.taskTextOutside1,
.taskTextOutside3 {
fill: black;
}
/* Active task */
.active0,
.active1,
.active2,
.active3 {
fill: #bfc7ff;
stroke: #534fbc;
}
.activeText0,
.activeText1,
.activeText2,
.activeText3 {
fill: black !important;
}
/* Completed task */
.done0,
.done1,
.done2,
.done3 {
stroke: grey;
fill: lightgrey;
stroke-width: 2;
}
.doneText0,
.doneText1,
.doneText2,
.doneText3 {
fill: black !important;
}
/* Tasks on the critical line */
.crit0,
.crit1,
.crit2,
.crit3 {
stroke: #ff8888;
fill: red;
stroke-width: 2;
}
.activeCrit0,
.activeCrit1,
.activeCrit2,
.activeCrit3 {
stroke: #ff8888;
fill: #bfc7ff;
stroke-width: 2;
}
.doneCrit0,
.doneCrit1,
.doneCrit2,
.doneCrit3 {
stroke: #ff8888;
fill: lightgrey;
stroke-width: 2;
cursor: pointer;
shape-rendering: crispEdges;
}
.doneCritText0,
.doneCritText1,
.doneCritText2,
.doneCritText3 {
fill: black !important;
}
.activeCritText0,
.activeCritText1,
.activeCritText2,
.activeCritText3 {
fill: black !important;
}
.titleText {
text-anchor: middle;
font-size: 18px;
fill: black;
}
/*

*/
.node text {
font-family: 'trebuchet ms', verdana, arial;
font-size: 14px;
}
div.mermaidTooltip {
position: absolute;
text-align: center;
max-width: 200px;
padding: 2px;
font-family: 'trebuchet ms', verdana, arial;
font-size: 12px;
background: #ffffde;
border: 1px solid #aaaa33;
border-radius: 2px;
pointer-events: none;
z-index: 100;
}

@font-face{font-family:KaTeX_AMS;src:url(fonts/KaTeX_AMS-Regular-f4c3270b.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular-e78f217c.woff) format("woff"),url(fonts/KaTeX_AMS-Regular-9971d270.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Bold-a2e05225.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold-bac61997.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold-743b42a3.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Regular-479a68ec.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular-a64e1342.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular-244db27f.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Bold-8e5f883e.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold-0a0aa194.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold-ad26cc83.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Regular-ae2b6f43.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular-f980ca72.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular-d459632e.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Bold-83f8b326.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold-d8a629d2.woff) format("woff"),url(fonts/KaTeX_Main-Bold-e69b9513.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-BoldItalic-0719833c.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic-5aeca883.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic-bdbadb27.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Italic-07510ed0.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic-8dd42e02.woff) format("woff"),url(fonts/KaTeX_Main-Italic-1b226149.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Regular-bd652252.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular-2dffc875.woff) format("woff"),url(fonts/KaTeX_Main-Regular-d9162dfe.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-BoldItalic-89e95efa.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic-65a38aa6.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic-fa111311.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-Italic-afeebb76.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic-da586018.woff) format("woff"),url(fonts/KaTeX_Math-Italic-55fbb3ac.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Bold-94911c5b.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold-bfe58d70.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold-f5f6a30d.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Italic-6a5b5cc9.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic-dabdeee1.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic-5110f85c.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Regular-7d5fa3e2.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular-48c7df6f.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular-8075d14a.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Script;src:url(fonts/KaTeX_Script-Regular-c472b570.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular-5acb381b.woff) format("woff"),url(fonts/KaTeX_Script-Regular-abb12fc2.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size1;src:url(fonts/KaTeX_Size1-Regular-feed6c70.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular-bdd0d5e0.woff) format("woff"),url(fonts/KaTeX_Size1-Regular-8cc60fd5.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size2;src:url(fonts/KaTeX_Size2-Regular-8a86a0af.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular-fd67fb35.woff) format("woff"),url(fonts/KaTeX_Size2-Regular-5976fffd.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size3;src:url(fonts/KaTeX_Size3-Regular-2c1ea030.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular-943c94f8.woff) format("woff"),url(fonts/KaTeX_Size3-Regular-e929f5d9.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size4;src:url(fonts/KaTeX_Size4-Regular-680d35e3.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular-68537743.woff) format("woff"),url(fonts/KaTeX_Size4-Regular-81ab95e4.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Typewriter;src:url(fonts/KaTeX_Typewriter-Regular-8a6d8ed8.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular-3e9e27f0.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular-29017475.ttf) format("truetype");font-weight:400;font-style:normal}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important}.katex .katex-version:after{content:"0.10.2"}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathdefault{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{width:0;position:relative}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:0 solid;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer,.katex .sizing{display:inline-block}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .op-limits>.vlist-t{text-align:center}.katex .accent>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;margin:0 -.025em;border-right:.05em solid;min-width:1px}.katex .mtable .vs-dashed{border-right:.05em dashed}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex svg path{stroke:none}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left}

@media print {
body {
overflow: visible !important;
}
.markdown-body table {
overflow: visible !important;
}
.ui-layout-north,
.ui-layout-center,
.ui-layout-toggler {
display: none !important;
}
.ui-layout-east {
left: 0 !important;
top: 0 !important;
right: 0 !important;
width: auto !important;
background: white !important;
overflow: visible !important;
}
.ui-layout-east .ui-layout-toggler {
display: none !important;
}
.ui-layout-east .markdown-body {
display: block !important;
padding: 20px !important;
}
.ui-layout-east .markdown-body [data-source-line] {
break-inside: avoid;
}
.markdown-body pre > code {
word-break: normal;
word-wrap: break-word;
white-space: pre-wrap;
}
}
body {
margin: 0;
padding: 0;
}
.ui-layout-east {
position: relative;
}
.markdown-body {
min-width: 256px;
max-width: 978px;
margin: 0 auto;
padding: 20px;
font-size: 14px;
tab-size: 4;
font-family: "-apple-system", BlinkMacSystemFont, "\5FAE\8F6F\96C5\9ED1", "PingFang SC", Helvetica, Arial, "Hiragino Sans GB", "Microsoft YaHei", SimSun, "\5B8B\4F53", Heiti, "\9ED1\4F53", sans-serif;
}
.markdown-body h1 {
font-size: 2.25em;
}
.markdown-body h2 {
font-size: 1.75em;
}
.markdown-body h3 {
font-size: 1.5em;
}
.markdown-body h4 {
font-size: 1.25em;
}
.markdown-body h5,
.markdown-body h6 {
font-size: 1em;
}
.markdown-body pre > code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace, sans-serif;
}
.markdown-body pre > code .zh-hans {
font-family: 'Microsoft YaHei', '\5FAE\8F6F\96C5\9ED1', SimSun, sans-serif;
}
.markdown-body img:not([src]),
.markdown-body img[src=""] {
display: none;
}
div[data-role=mermaid] {
text-align: center;
}
hr.footnotes-sep {
margin: 64px 0 32px 0;
height: 1px;
}
.footnotes {
font-size: 90%;
padding-left: 16px;
}
li.footnote-item > p {
margin: 8px 0;
}
.success,
.info,
.warning,
.danger {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}
.success > p:last-child,
.info > p:last-child,
.warning > p:last-child,
.danger > p:last-child {
margin-bottom: 0;
}
.success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
.warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
.danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
abbr[title] {
cursor: help;
border-bottom: 1px dotted #777;
}
ul.table-of-contents {
list-style-type: none;
}
ul.table-of-contents li {
margin: 4px 0;
}
.markdown-body table {
width: auto;
display: table;
}
.markdown-body table td {
word-break: break-all;
}
.markdown-body.ace_search .highlight pre,
.markdown-body.ace_search pre {
overflow: visible !important;
width: -webkit-fit-content !important;
width: fit-content !important;
}
-->

AntData ORM框架是我维护的一个开源ORM框架

https://github.com/yuzd/AntData.ORM

该框架是在Linq2db这个优秀的linq转sql引擎基础上进行改造而来的。

分离了linq2sql引擎和db执行逻辑。

画一个图的话 应该是这样的:

分表分库功能设计

框架内置目前使用比较多的两种分片模式:

  • 取模 (mod)
  • 范围 (range)

为了让框架更容易扩展

  • 开放分片策略的接口 当有自定义分片规则可以继承实现

下面我用内置的 取模 分片模式来说明 ,运行环境: netcore平台

1. DB Sharding

db配置:

  • Provider 指定为 mysql
  • Name 是逻辑名称 可以随意指定
  • ShardingStrategy 指定分片的逻辑处理
  • ConnectionItemList 指定一个或多个db链接配置

注意:

class=AntData.DbEngine.Sharding.ModShardingStrategy;column=ID;mod=2;shardByDB=true

的意思是:

采用内置的取模分片法,走分片的字段叫ID mod为2 也就是1分为2个 分别是 (0 和 1),所以下面的ConnectionItemList指定的 Sharding分别是0和1的数据库连接

按照上面的配置的话,当满足

  • 表还有字段ID
  • db搜索的条件含有id字段,或者 db更新的条件含有id字段 或者db删除的条件含有id字段

都应该走取模算法来走对应的db。

下面来测试它

DB Sharding 使用场景举例说明


/// <summary>
/// 测试mod分库插入到testorm2数据库
/// </summary>
[TestMethod]
public void TestMethod6_01()
{
//id查询 1 mod 2 = 1 所以会走到 testorm2数据库
var id = 1;
var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(1));
if (odIsExist)
{
return;
}
var order = new Order
{
ID = 1,
Name = "上海大学"
}; var result = DB.Insert(order);
Assert.AreEqual(result, 1); }

/// <summary>
/// 测试mod分库插入到testorm1数据库
/// </summary>
[TestMethod]
public void TestMethod6_02()
{ var id = 2;
var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(2));
if (odIsExist)
{
return;
}
var order = new Order
{
ID = 2,
Name = "北京大学"
}; var result = DB.Insert(order);
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分库 查询testorm2数据库
/// </summary>
[TestMethod]
public void TestMethod6_03()
{
var id = 1;
var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(1));
Assert.IsNotNull(tb1);
} /// <summary>
/// 测试mod分库 查询testorm1数据库
/// </summary>
[TestMethod]
public void TestMethod6_04()
{
var id = 2;
var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(2));
Assert.IsNotNull(tb1);
} /// <summary>
/// 测试mod分库 不指定sharing column 查询叠加
/// </summary>
[TestMethod]
public void TestMethod6_05()
{
var tb1 = DB.Tables.Orders.ToList();
Assert.IsNotNull(tb1);
Assert.AreEqual(tb1.Count, 2); var odIsExist = DB.Tables.Orders.Where(r => r.ID.Equals(1) || r.ID.Equals(2)).ToList();
Assert.AreEqual(odIsExist.Count, 2);
} /// <summary>
/// 测试mod分库修改到testorm2数据库
/// </summary>
[TestMethod]
public void TestMethod6_06()
{
var id = 1;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(1)).Set(r => r.Name, y => y.Name + "1").Update();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分库修改到testorm1数据库
/// </summary>
[TestMethod]
public void TestMethod6_07()
{
var id = 2;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(2)).Set(r => r.Name, y => y.Name + "1").Update();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分库删除到testorm2数据库
/// </summary>
[TestMethod]
public void TestMethod6_08()
{
var id = 1;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(1)).Delete();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分库删除到testorm1数据库
/// </summary>
[TestMethod]
public void TestMethod6_09()
{
var id = 2;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(2)).Delete();
Assert.AreEqual(result, 1);
} [TestMethod]
public void TestMethod7_01()
{
var id = 2; //var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(id)); var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(2));
if (odIsExist)
{
return;
} } /// <summary>
/// 测试mod分库批量分别插入到testorm1 和 testorm2数据库
/// </summary>
[TestMethod]
public void TestMethod7_02()
{
var orderList = new List<Order>();
orderList.Add(new Order
{
ID = 3,
Name = "上海大学"
});
orderList.Add(new Order
{
ID = 4,
Name = "上海大学"
});
//没有指定 shading column的话是默认分到第一个分片
orderList.Add(new Order
{
ID = null,
Name = "上海大学"
});
var rows = DB.BulkCopy(orderList);
Assert.AreEqual(rows.RowsCopied, 3);
} /// <summary>
/// 不指定sharing column 删除会叠加
/// </summary>
[TestMethod]
public void TestMethod7_03()
{
var odIsExist = DB.Tables.Orders.Delete();
Assert.AreEqual(odIsExist, 3); }

2. Table Sharding

  • Provider 指定为 mysql
  • Name 是逻辑名称 可以随意指定
  • ShardingStrategy 指定分片的逻辑处理
  • ConnectionItemList 指定一个db链接配置

针对分表要对 dbmodels 做一个小修改

class=AntData.DbEngine.Sharding.ModShardingStrategy;column=ID;mod=2;tableSharding=0,1;shardByDB=false;shardByTable=true

的意思是:

采用内置的取模分片法,走分片的字段叫ID mod为2 也就是1分为2个 分别是 (0 和 1),所以下面的ConnectionItemList指定的 Sharding分别是order_0和order_1的数据

按照上面的配置的话,当满足

  • 表还有字段ID
  • db搜索的条件含有id字段,或者 db更新的条件含有id字段 或者db删除的条件含有id字段

都应该走取模算法来走对应的table。

下面来测试它

Table Sharding 使用场景举例说明


/// <summary>
/// 测试mod分表插入到testorm3数据库的orders_1表里面
/// </summary>
[TestMethod]
public void TestMethod1_01()
{
var id = 1;
var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(id));
if (odIsExist)
{
return;
} var order = new Orders
{
ID = id,
Name = "订单1"
}; var result = DB.Insert(order);
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分表插入到testorm3数据库的orders_0表里面
/// </summary>
[TestMethod]
public void TestMethod1_02()
{
var id = 2;
var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(id));
if (odIsExist)
{
return;
}
var order = new Orders
{
ID = id,
Name = "订单2"
}; var result = DB.Insert(order);
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分表 查询testorm3数据库orders_1表
/// </summary>
[TestMethod]
public void TestMethod1_03()
{
var id = 1;
var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(id));
Assert.IsNotNull(tb1);
} /// <summary>
/// 测试mod分表 查询testorm3数据库orders_0表
/// </summary>
[TestMethod]
public void TestMethod1_04()
{
var id = 2;
var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(id));
Assert.IsNotNull(tb1);
} /// <summary>
/// 测试mod分表 不指定sharing column 查询叠加
/// </summary>
[TestMethod]
public void TestMethod1_05()
{
var tb1 = DB.Tables.Orders.ToList();
Assert.IsNotNull(tb1);
Assert.AreEqual(tb1.Count, 2); var odIsExist = DB.Tables.Orders.Where(r => r.ID.Equals(1) || r.ID.Equals(2)).ToList();
Assert.AreEqual(odIsExist.Count, 2);
} /// <summary>
/// 测试mod分表修改到testorm3数据库orders_1表
/// </summary>
[TestMethod]
public void TestMethod1_06()
{
var id = 1;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(id)).Set(r => r.Name, y => y.Name + "1").Update();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分表修改到testorm3数据库orders_0表
/// </summary>
[TestMethod]
public void TestMethod1_07()
{
var id = 2;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(id)).Set(r => r.Name, y => y.Name + "1").Update();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分表删除到testorm3数据库orders_1表
/// </summary>
[TestMethod]
public void TestMethod6_08()
{
var id = 1;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(id)).Delete();
Assert.AreEqual(result, 1);
} /// <summary>
/// 测试mod分表删除到testorm3数据库orders_0表
/// </summary>
[TestMethod]
public void TestMethod6_09()
{
var id = 2;
var result = DB.Tables.Orders.Where(r => r.ID.Equals(id)).Delete();
Assert.AreEqual(result, 1);
}
/// <summary>
/// 测试mod分库批量分别插入到testorm3数据库orders_0表 orders_1表
/// </summary>
[TestMethod]
public void TestMethod7_01()
{ var orderList = new List<Orders>();
orderList.Add(new Orders
{
ID = 3,
Name = "上海大学"
});
orderList.Add(new Orders
{
ID = 4,
Name = "上海大学"
});
//没有指定 shading column的话是默认分到第一个分片
orderList.Add(new Orders
{
ID = null,
Name = "上海大学"
});
var rows = DB.BulkCopy(orderList);
Assert.AreEqual(rows.RowsCopied, 3);
} /// <summary>
/// 不指定sharding 字段会删除所有子表
/// </summary>
[TestMethod]
public void TestMethod7_03()
{
var odIsExist = DB.Tables.Orders.Delete();
Assert.AreEqual(odIsExist, 3); }

总结

目前在AntData orm中使用分库分表其实是根据查询的字段来匹配取模或者区间来进行分片,然后只需要配置上进行修改即可。对于实际业务上orm的写法是不需要变化的

ORM框架对分表分库的实现的更多相关文章

  1. ORM框架对分表分库之分库和分表指定不同的字段

    ORM框架分库分表已实现了 只分表(根据指定字段) 点我查看demo 只分库(根据指定字段) 点我查看demo 既分库又分表(根据相同的字段) 点我查看demo 上面几点之前我在博客中已经写了使用介绍 ...

  2. 1.ORM介绍,基本配置及通过ORM框架创建表

    1.介绍 ORM全拼Object-Relation Mapping(对象-关系映射) 作用:主要实现模型对象到关系数据库数据的映射 通过ORM框架作为一个中间者或者是一个桥梁,开发者通过定义模型类,属 ...

  3. MySQL—ORM框架,sqlalchemy模块

    武老师博客:ORM框架介绍 import os #1.当一类函数公用同样参数时候,可以转变成类运行 - 分类 #2.面向对象: 数据和逻辑组合在一起了 #3. 一类事物共同用有的属性和行为(方法) # ...

  4. MySQL(ORM框架)

    day63 参考:http://www.cnblogs.com/wupeiqi/articles/5713330.html SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件, ...

  5. ORM框架 和 面向对象编程

    ORM框架: 1.SQLAlchemy:  - 作用   1.提供简单的规则   2.自动转换成SQL语句  - DB first/code first   DB first: 手动创建数据库以及表  ...

  6. .NET ORM 分表分库【到底】怎么做?

    理论知识 分表 - 从表面意思上看呢,就是把一张表分成N多个小表,每一个小表都是完正的一张表.分表后数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面.分表后单表的并发能力提高了 ...

  7. 单表ORM框架

    基本描述 1.首先是一个单表的ORM框架,多表连接查询请使用视图或者使用SqlHelper查询,然后转换成实体集合. 2.目前仅完成基本结构和MySQL部分. 3.目前欠缺Lambda表达式解析,所以 ...

  8. flask的orm框架(SQLAlchemy)-创建表

    # 转载请留言联系 ORM 是什么? ORM,Object-Relation Mapping.意思就是对象-关系映射.ORM 主要实现模型对象到关系数据库数据的映射. 优点 : 只需要面向对象编程, ...

  9. sqlite表结构动态读取工具(Chole ORM框架)

    Chole ORM框架 sqlIte于嵌入式数据库读取比较有利,不需要安装office也可以进行,可以在服务器系统当中使用. 所以我开发了这款工具,然后就是为了动态的读取表结构,然后根据表结构加载所有 ...

随机推荐

  1. 为Python安装pip

    Python及操作系统的支持 Python 2.6, 2.7, 3.2, 3.3, 3.4 Unix/Linux, OS X, 以及 Windows   默认包含 Python 2.7.9 及以后的版 ...

  2. DJango中开启事务的两种方式

    目录 Django中开启事务的两种方式 第一种 第二种 Django中开启事务的两种方式 第一种 from django.db import transaction with transaction. ...

  3. css 实现九宫格

    1.自己写了一个,写完对比了下别人写的发现自己写的太low.故就不写自己太差劲的了. 别人写的我总结优化了一下,如果不用写内容去掉position,content简单也是可以的. <!DOCTY ...

  4. CKafka如何助力腾讯课堂实现百万消息稳定互动?

    疫情期间,为了保障国内学子的正常学习进度,腾讯课堂积极响应国家“停工不停学”的号召,紧急上线疫情期间专用的“老师极速版”,使广大师生足不出户,即可快速便捷的完成线上开课.面对线上课堂百万量级的互动消息 ...

  5. Django 配置使用日志

    一. Django中使用日志 Django中使用日志其实非常简单,只需要在项目使用的配置文件中(如果没有自定义,那么就是settings.py中)加以下设置即可,同时可以根据自己的需求进行修改: # ...

  6. FormDataBodyPart获取表单文件名乱码解决方法

    FormDataMultiPart formData=; FormDataBodyPart filePart=; filePart.getFormDataContentDisposition().ge ...

  7. vue基础指令学习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Python第五章-内置数据结构04-字典

    Python 内置的数据结构 四.字典(dict) 字典也是 python 提供给我们的又一个非常重要且有用的数据结构. 字典在别的语言中有时叫关联数组.关联内存.Map等. 字典中存储的是一系列的k ...

  9. python txt文件批处理

    首先,切换文件路径到所在文件夹 然后,将txt文件内容按行读取,写入到all.txt def txtcombine(): files=glob.glob('*.txt') all = codecs.o ...

  10. MATLAB中mean的用法

    https://blog.csdn.net/wangyang20170901/article/details/78745587 MATLAB中mean的用法 转载仙女阳 最后发布于2017-12-07 ...