搜索​​​​

清除过滤器
文章
Jingwei Wang · 九月 27, 2021

IRIS 2021 技术文档 First Look 21 数据弹性(恢复、高可用与灾备)和镜像

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .md-inline-math .MathJax_SVG .noError { display: none !important; } .html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; } .md-fences-math .MathJax_SVG_Display, .md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: visible; display: block !important; } .MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; } .MathJax_SVG .MJX-monospace { font-family: var(--monospace); } .MathJax_SVG .MJX-sans-serif { font-family: sans-serif; } .MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; zoom: 90%; } #math-inline-preview-content { zoom: 1.1; } .MathJax_SVG * { transition: none; } .MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-math .MathJax_SVG_Display { margin-top: 8px; cursor: default; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } .CodeMirror { height: auto; } .CodeMirror.cm-s-inner { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-scroll { overflow: auto hidden; z-index: 3; } .CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); } .CodeMirror-gutters { border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; white-space: nowrap; background-position: inherit; background-repeat: inherit; } .CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); } .cm-s-inner .cm-keyword { color: rgb(119, 0, 136); } .cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); } .cm-s-inner .cm-number { color: rgb(17, 102, 68); } .cm-s-inner .cm-def { color: rgb(0, 0, 255); } .cm-s-inner .cm-variable { color: rgb(0, 0, 0); } .cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); } .cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); } .cm-s-inner .cm-string { color: rgb(170, 17, 17); } .cm-s-inner .cm-property { color: rgb(0, 0, 0); } .cm-s-inner .cm-operator { color: rgb(152, 26, 26); } .cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); } .cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); } .cm-s-inner .cm-meta { color: rgb(85, 85, 85); } .cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); } .cm-s-inner .cm-builtin { color: rgb(51, 0, 170); } .cm-s-inner .cm-bracket { color: rgb(153, 153, 119); } .cm-s-inner .cm-tag { color: rgb(17, 119, 0); } .cm-s-inner .cm-attribute { color: rgb(0, 0, 204); } .cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); } .cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); } .cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); } .cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); } .cm-negative { color: rgb(221, 68, 68); } .cm-positive { color: rgb(34, 153, 34); } .cm-header, .cm-strong { font-weight: 700; } .cm-del { text-decoration: line-through; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-error { color: red; } .cm-invalidchar { color: red; } .cm-constant { color: rgb(38, 139, 210); } .cm-defined { color: rgb(181, 137, 0); } div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); } .cm-s-inner .CodeMirror-activeline-background { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror { position: relative; overflow: hidden; } .CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-sizer { position: relative; } .CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; } .CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; } .CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; } .CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; } .CodeMirror-gutter-filler { left: 0px; bottom: 0px; } .CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; } .CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; border: none !important; background-position: 0px 0px !important; } .CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-lines { cursor: text; } .CodeMirror pre { border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-width: 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; background-position: 0px 0px; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-code pre { border-right-width: 30px; border-right-style: solid; border-right-color: transparent; width: fit-content; } .CodeMirror-wrap .CodeMirror-code pre { border-right-style: none; width: auto; } .CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; } .CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; } .CodeMirror-measure pre { position: static; } .CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right-style: none; width: 0px; } .CodeMirror div.CodeMirror-cursor { visibility: hidden; } .CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; } .cm-searching { background-color: rgba(255, 255, 0, 0.4); } span.cm-underlined { text-decoration: underline; } span.cm-strikethrough { text-decoration: line-through; } .cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); } .cm-tw-deleted { text-decoration: line-through; } .cm-tw-header5 { font-weight: 700; } .cm-tw-listitem:first-child { padding-left: 10px; } .cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; } .cm-tw-underline { text-decoration: underline; } @media print { .CodeMirror div.CodeMirror-cursor { visibility: hidden; } } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 目录技术概要:数据弹性和镜像数据弹性(Data Resiliency):InterSystems IRIS 提供什么数据弹性(Data Resiliency):InterSystems IRIS 如何提供写入映像日志(Write Image Journaling):防止物理数据损坏和丢失 日志(Journaling):防止逻辑数据损坏和丢失 镜像(Mirroring):高可用性和灾备解决方案 镜像虚拟化平台使用InterSystems IRIS镜像一个数据库:试一试了解有关 InterSystems 数据弹性的更多信息技术概要:数据弹性和镜像本技术概要(First Look)将向您介绍InterSystems IRIS®数据平台的数据弹性(data resiliency)功能。数据弹性包括三个目标------崩溃恢复、高可用性和灾备------这些都是通过 InterSystems IRIS 的几个功能实现的。InterSystems IRIS 的主要功能之一是能够利用逻辑数据复制提供对数据的连续和不间断访问。数据可以同步复制,以允许在各种故障情况下自动故障转移而不会丢失数据,无论是计划内的(例如软件升级)还是计划外的(例如硬件故障)。同步复制数据需要两个节点之间低延迟,因此并不总是适用于跨国家传输数据的灾备(DR)场景。对于这些场景,InterSystems IRIS 提供了内置的异步数据复制。InterSystems IRIS 的镜像功能提供了高可用性。在了解了 InterSystems IRIS 数据弹性后,您将创建一个镜像(mirror),在主成员上进行数据更改,并自动同步复制到备份成员上,然后关闭主成员,使镜像故障转移到备份上。这些活动只使用默认设置,因此您可以熟悉这些功能的基本原理。有关完整的文档,请参见 InterSystems IRIS Data Integrity Guide(《InterSystems IRIS 数据完整性指南》)。[]{#1_Data_Resiliency:_What_InterSystems_IRI .anchor}要浏览所有的技术概要(First Looks),包括那些可以在免费的云实例或 web 实例上执行的技术概要(First Looks),请参见InterSystems 技术概要。数据弹性(Data Resiliency):InterSystems IRIS 提供什么数据弹性涵盖多个主题,但它们都围绕着一个原则:一旦数据被记录在数据平台上,无论发生什么,它都是可以访问的。为了实现这一目标,有几个不同的地方需要解决:即使在发生错误或电源故障的情况下,也能保证数据的有效性从 InterSystems IRIS 服务器的本地故障中进行崩溃恢复,无论是物理故障还是软件相关的故障。防止全站点灾难(断电、网络问题等。)为了满足这些要求,InterSystems IRIS 提供了:结构化数据库完整性(磁盘上数据库块的内容)和防止内部完整性故障(数据库中表示的数据)通过事务处理、锁定和自动回滚实现逻辑数据库完整性内置的高可用性解决方案,具有自动故障转移功能逻辑数据复制,最大限度地降低了结转物理损坏的风险,并且不依赖共享资源计划内和计划外停机的解决方案通过地理上分散的灾难恢复配置带来业务连续性优势InterSystems IRIS 数据弹性全天候保护您生产系统上的数据。数据弹性:InterSystems IRIS 如何提供数据弹性(Data Resiliency):InterSystems IRIS 如何提供系统停机的成本从数千美元到数百万美元不等,具体取决于停机的类型和时间长度以及受影响的系统类型。从停机中快速恢复固然很重要,但恢复数据并确保您的数据不会丢失和损坏的能力也很重要。InterSystems IRIS 写入映像日志技术(write image journaling technology)提供结构化数据库的完整性(磁盘上数据库块的内容),并防止由于系统崩溃而导致的内部完整性故障(数据库中表示的数据)。InterSystems IRIS 备份和日志系统提供物理完整性故障的快速恢复。数据弹性通过事务处理[]{#2.1_Write_Image_Journaling:_Protection_A .anchor}、锁定和自动回滚确保逻辑数据库完整性。除了日志提供的功能外,InterSystems IRIS 还允许您对数据库进行镜像,以提供快速、高效的数据复制和灾难恢复。写入映像日志(Write Image Journaling):防止物理数据损坏和丢失 任何突然的、意外的磁盘或计算机操作中断都可能在第一个数据块(block)被写入后但在最后一个数据块(block)被更新前停止对多个数据库块的更新。其后果可能与数据库完全不可用一样严重,所有数据都无法通过正常方式恢复。 InterSystems IRIS 写入映像日记技术(Write image journaling,WIJ)可以防止这种数据损坏。它可以防止不完整的更新导致不一致的数据库结构。写入映像日志(WIJ)通过使用两阶段(two-phase)方法来保护数据库更新。InterSystems IRIS 实例首先将更新从内存写入过渡日志,即 IRIS.WIJ 文件,然后再写入数据库。如果系统在第一阶段崩溃,则删除更新而不对数据库进行任何更改;如果崩溃发生在第二阶段,您可以在恢复时重新应用写入映像日志(WIJ)的更新,确保对数据库进行所有更新。写入守护进程(The write daemon)在 InterSystems IRIS 启动时创建写入映像日志(WIJ)文件,并在将数据库更新写入 InterSystems IRIS 数据库之前记录 WIJ 中的数据库更新。一旦它输入对 WIJ 的所有更新,它就在文件中设置一个标志,第二阶段开始,写入守护进程将 WIJ 中记录的同一组块写入磁盘上的数据库中。当第二阶段完成时,写入守护进程在 WIJ 中设置一个标志,表示它已被删除。当 InterSystems IRIS 启动时,它会自动检查 WIJ,并在检测到发生异常关机时运行恢复程序。当该程序成功完成时,将恢复数据库的内部完整性。InterSystems IRIS 还在关机后运行 WIJ 恢复作为安全预防措施,以确保数据可以安全备份。根据 WIJ 在两阶段(two-phase)写入协议进程中的位置,恢复执行以下操作:如果崩溃发生在对 WIJ 的最后一次更新完成之后,但在对数据库的相应更新完成之前,那么 WIJ 将被恢复。如果崩溃发生在最后一次 WIJ 更新被持久地写入数据库之后,则会在最近的 WIJ 更新和受影响的数据库之间进行块比较。日志(Journaling):防止逻辑数据损坏和丢失 日志(Journaling)是一个可以在每个数据库基础上启用的功能,它提供所有数据库修改的完整记录。在发生崩溃的情况下,可以在恢复备份之后,从日志中重新应用自最近备份以来所做的更新,以使数据库恢复到发生崩溃的点。InterSystems IRIS 恢复过程通过使用"前滚"的方法提供最大程度的保护。如果发生系统崩溃,恢复机制将完成正在进行的更新。它还保护了更新的顺序;如果恢复后数据库中存在一个更新,那么之前的所有更新也都存在。这可以保护数据弹性:InterSystems IRIS 如何提供增量备份文件结构以及数据库。您可以在崩溃恢复后运行有效的增量备份。日志是数据弹性的第三个功能:镜像的基础。镜像(Mirroring):高可用性和灾备解决方案 InterSystems IRIS 镜像(Mirroring)属于系统可用性策略中的自动故障转移类别。镜像为数据库的可用性提供了全面、可靠和强健的企业解决方案。依赖共享资源(如共享磁盘)的传统可用性解决方案往往容易受到与该共享资源有关的单点故障的影响。镜像通过在主镜像成员和备份镜像成员上维护独立的资源来降低这种风险。此外,通过使用逻辑数据复制,镜像避免了与物理复制技术(如基于 SAN 的复制)相关的风险,包括无序更新和结转损坏。InterSystems IRIS 为高可用性镜像提供了两个选项:镜像(Mirroring)和虚拟化(Virtualization)。镜像具有自动故障转移功能的 InterSystems IRIS 镜像依赖于完全独立系统之间的逻辑数据复制。这避免了在为多个系统使用共享存储时出现单点故障的风险。它还确保在所有故障场景(系统、存储和网络)中,生产系统可以立即将故障转移到备用 InterSystems IRIS 实例。在 InterSystems IRIS 镜像中,一个被称为主故障转移成员的 InterSystems IRIS 实例,提供对生产数据库的访问。另一台主机上的另一个实例(称之为备份故障转移成员),与主服务器同步通信,检索主服务器的日志记录,确认收到日志记录,并将它们应用到同一数据库的自己的副本上。通过这种方式,主服务器和备份服务器总是知道备份服务器是否拥有来自主服务器的最新日志文件,因此可以精确地将其数据库与主服务器上的数据库进行同步。InterSystems IRIS 镜像的另一大功能是允许配置一个特殊的异步成员,它可以从整个企业的多个镜像中接收更新。您可以为单个镜像的灾备配置一个异步成员,这允许它在需要时无缝地替代一个故障转移成员的位置。一个镜像最多可以包括 16 个成员,这使您可以配置多个地理上分散的 灾备(DR) 异步成员。这种模式为分布式数据复制提供了一个强健的框架,从而确保业务连续性有利于组织。另一个好处是,使用异步成员的镜像允许单个系统充当全面的企业数据仓库。这为您提供了企业范围内的数据挖掘和业务智能。虚拟化平台虚拟化平台通常提供 高可用(HA) 功能,这些功能通常监视客户操作系统和运行它的硬件的状态。在虚拟化环境中使用镜像,构成镜像的 InterSystems IRIS 实例安装在虚拟主机上,创造了一个混合的高可用性解决方案,结合了镜像和虚拟化的优势。虽然镜像通过自动故障转移对计划内或计划外的故障提供即时响应,但虚拟化 HA 软件在计划外的机器或 OS 故障后自动重新启动托管镜像成员的虚拟机。这允许失败的成员快速重新加入镜像,以充当备份(或在必要时作为主要成员接管)。在任何一个发生故障时,虚拟化平台都会根据需要在备用硬件上自动重新启动故障的虚拟机。当 InterSystems IRIS 实例重新启动时,它会自动执行正常的启动恢复,保持结构和逻辑完整性,就像您在物理服务器上重新启动 InterSystems IRIS 一样。使用InterSystems IRIS镜像一个数据库:试一试现在您已经对 InterSystems IRIS 数据弹性及其提供的功能有了一些背景知识,让我们通过镜像来了解其中的一部分。使用 InterSystems IRIS 设置镜像环境很容易。您可以使用自动提供、部署和配置镜像的 InterSystems 云管理器(InterSystems Cloud Manager,ICM),也可以使用管理门户(Management Portal)进行手动配置。本文档介绍如何使用 ICM 部署镜像。(关于使用管理门户[Management Portal]使用两个已安装的 InterSystems IRIS 实例创建镜像的步骤,请参见 High Availability Guide[《高可用性指南》]的 "Mirroring[镜像]"一章中的 Creating a Mirror[创建镜像])。在这种情况下,您将在亚马逊网络服务(Amazon Web Services)公共云中部署一对镜像的 InterSystems IRIS 实例。要做到这一点,请按照《技术概要:InterSystems 云管理器》中 Try It! Deploy InterSystems IRIS in the Cloud with ICM(试一试!使用 ICM 在云中部署 InterSystems IRIS)的 Customize the Sample Configuration Files(自定义示例配置文件)一节中的步骤,进行以下修改:在 defaults.json 文件中,添加"Mirror": "True"。自定义 definitions.json 文件,添加一个 AR 节点定义,指定 arbiter 映像。[ { "Role": "DATA", "Count": "2", "LicenseKey": "ubuntu-sharding-iris.key" }, { "Role": "AR", "Count": "1", "StartCount": "3", "DockerImage": "intersystems/arbiter:stable" }]DockerImage 属性必须是 AR 节点定义的一部分,因为 AR 节点使用不同于 InterSystems IRIS 节点(如 DATA)的 InterSystems 映像(image)。您必须确保 arbiter 映像(image)在本地可用;有关此操作的信息,请参见《技术概要:InterSystems 云管理器》中的 Identify Docker Repository and Credentials(识别 Docker 存储库和凭证)。一旦您定制了配置文件,包括这些变化,就继续执行程序。当您完成了"部署 InterSystems IRIS"步骤(icm run 命令),并且镜像已经部署在云中,继续使用 ICM 命令行来尝试镜像:在主故障转移成员上设置 global,并验证它在备份故障转移成员上也被设置了。触发计划的从主服务器到备份服务器的故障转移。要做到这一点,请使用以下程序:在 ICM 命令行上,通过输入 icm inventory 命令,查看您的镜像成员的名称和镜像角色,其中列出了您已经配置的云主机节点。ICM 提供的节点被命名为 Label-Role-Tag-NNNN;其中 Role 是 ICM 节点类型,在本例中是 DATA,其他部分由您赋值。镜像成员用 +(加号)表示初始主节点,用 -(减号)表示初始备份。本程序其余部分的示例假设您把 label 字段设置为 Acme,把 tag 字段设置为 TEST,从而产生如下所示的 icm inventory 输出:$ icm inventoryMachine IP Address DNS Name Region ZoneAcme-DATA-TEST-0001+ 00.53.183.209 ec2-00-53-183-209.us-west-1.compute.amazonaws.com us-west-1 cAcme-DATA-TEST-0002- 00.53.183.185 ec2-00-53-183-185.us-west-1.compute.amazonaws.com us-west-1 c使用InterSystems IRIS镜像一个数据库:试一试注意: 节点编号和镜像角色之间没有关系。 + 和 - 符号仅表示初始镜像赋值;对于实时镜像状态,请使用 icm ps 命令。通过输入命令在主镜像成员上打开 InterSystems 终端(Terminal):$ icm session -interactive -machine Acme-DATA-TEST-0001当终端(Terminal)窗口打开时,您就处于 DB 命名空间,它被映射到镜像数据库 DB;ICM 默认创建了这两个数据库。输入以下命令在 DB 数据库中创建 global(globals 在 InterSystems IRIS 数据库中存储数据):DB> Set \^myfirstglobal="congratulations"输入以下命令来显示 global 的值:DB> Write \^myfirstglobal congratulations使用以下命令为备份故障转移成员打开终端(Terminal)窗口:$ icm session -interactive -machine Acme-DATA-TEST-0002输入相同的 Write 命令;global 已经存在,并且其值是您在主服务器上设置的。数据被自动同步地镜像到备份中的 DB 数据库。DB> Write \^myfirstglobal congratulations备份中的镜像数据库是只读的;如果您试图改变 global 的值,您会得到一个错误。DB> Set \^myfirstglobal="what next?"<PROTECT>返回到 ICM 命令行,使用以下命令关闭并重新启动其容器内的主要 InterSystems IRIS 实例(ICM 默认将其命名为 IRIS):$ icm exec -command "iris stop IRIS quietly restart" -machine Acme-DATA-TEST-0001注意: -quietly 参数防止 iris stop 命令提示发行者,这将导致 ICM 等待直到超时。另外,您可以交互式地执行命令,如下所示,从而允许您响应提示:$ icm exec -command "iris stop IRIS restart" -interactive -machine Acme-DATA-TEST-0001等待几秒钟,然后返回 Acme-DATA-TEST-0002 上的终端(Terminal)窗口。当主服务器由于计划或计划外的故障而不可用时,镜像将自动故障转移到备份服务器,备份服务器将成为新的主服务器。因此,Acme-DATA-TEST-0002 已经成为主服务器,您现在可以更改 global 的值了。DB> Set \^myfirstglobal="what next?"DB> Write \^myfirstglobal what next?使用 icm ps 命令显示新的镜像角色:$ icm ps了解有关 InterSystems 数据弹性的更多信息为以前的主服务器 Acme-DATA-TEST-0001 打开一个新的终端(Terminal)窗口,重新启动时发现 Acme-DATA-TEST-0002 现在是主服务器,因此成为新的备份。因此,global 的值已经被更新为您在新的主节点上设置的值,您无法更改它。$ icm session -interactive -machine Acme-DATA-TEST-0001 DB> Write \^myfirstglobalwhat next?DB> Set \^myfirstglobal="another First Look!"<PROTECT>备份镜像成员随时准备接管主成员,以保持数据库可用,并保护您的数据不被损坏和丢失。当您完成镜像体验后,请务必返回《技术概要:InterSystems 云管理器》中的 Unprovision the Infrastructure(取消配置基础设施),并根据取消配置您的云节点的程序进行操作。因为 AWS 和其他公共云[]{#4_Learn_More_About_InterSystems_Data_Res .anchor}平台实例会不断产生费用,所以在使用完基础设施后立即取消配置是很重要的。了解有关 InterSystems 数据弹性的更多信息要了解有关 InterSystems IRIS 数据弹性和 ICM 的更多信息,请参见进一步阅读:High Availability Guide(《高可用性指南》)Data Integrity Guide(《数据完整性指南》)InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)What is InterSystems Cloud Manager?(《什么是 InterSystems 云管理器?》)(视频)The ICM Experience:Pat and Tracy (《ICM 体验:Pat 和 Tracy》) (视频)InterSystems in the Cloud Experience(《云体验中的 InterSystems》) (在线体验)
文章
Jingwei Wang · 九月 26, 2021

IRIS 2021 技术文档 First Look 11 用于.Net的InterSystems IRIS Native API

本文解释了如何使用 InterSystems IRIS Native 从 .NET 应用程序访问 InterSystems IRIS®数据平台 globals。IRIS Native 还允许您运行ObjectScript 方法、函数和Routine。在本文中,您首先将连接到 InterSystems IRIS。然后您将在 InterSystems IRIS 中设置和检索一个global 节点的值,并在另一个 global 节点上进行迭代。您还将调用 InterSystems IRIS 类方法。所有这些活动都将在 .NET 应用程序中执行。 为了让您体验 IRIS Native,而又不陷入细节困境,本次探索特意设计得很简洁。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您把 IRIS Native 引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 IRIS Native 的探索与真实的情况相混淆! Globals 简介 InterSystems IRIS 提供了一种易于使用的方法来将数据存储在持久的多维数组中。global 是存储在 InterSystems IRIS 物理数据库中的多维数组。在应用程序中,globals 到物理数据库的映射基于当前命名空间,命名空间提供一个或多个物理数据库的逻辑统一视图。例如,要使用一个名为 ^Settings 的 global 将值 "Red "与键 "Color "关联起来,打开 InterSystems 终端并输入以下代码: set ^Settings("Color")="Red" 您可以利用 globals 的多维特性来定义一个更复杂的结构: set ^Settings("Auto1","Properties","Color") = "Red" set ^Settings("Auto1","Properties","Model") = "SUV" set ^Settings("Auto2","Owner") = "Mo" set ^Settings("Auto2","Properties","Color") = "Green" 探索 IRIS Native 现在,您已经准备好实验 IRIS Native 了。下面的简短演示将向您演示如何在 .NET 应用程序中使用 IRIS Native。(想试试 InterSystems IRIS .NET 开发和互操作性功能的在线视频演示?请看.NET 快速入门! 用前须知 要使用该程序,您需要一个安装了 .NET 框架和 Visual Studio 的 Windows 系统,以及一个运行中的 InterSystems IRIS 实例来连接。您对InterSystems IRIS 的选择包括多种类型的已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见InterSystems IRIS 基础:连接一个 IDE中的部署InterSystems IRIS 。使用同一文档中的InterSystems IRIS 连接信息和 .Net IDE 中的信息将 Visual Studio 连接到您的 InterSystems IRIS 实例。 配置 Visual Studio 项目 首先,打开 Visual Studio 并创建一个新的控制台应用程序项目,选择 Visual C# 和 Console App (.NET Framework)(控制台应用程序(.NET 框架))选项。对于 Name(名称)字段,输入 netnative。 添加程序集引用 InterSystems.Data.IRISClient.dll 程序集必须存在于您的本地系统中;您可以从 https://github.com/intersystems/quickstarts-dotnet/tree/master/EFPlay/bin/Debug 下载它。如果 InterSystems IRIS 安装在您的本地系统或您可以访问的另一个系统上,则该程序集已经安装在子目录 install-dir\dotnet\bin\v4.5 中,其中 install-dir 是该实例的安装目录。 要将 InterSystems.Data.IRISClient.dll 的程序集引用添加到项目: 从 Visual Studio 主菜单中,选择 Project(项目) > Add Reference(添加引用)... 在出现的窗口中,点击 Browse(浏览).... 浏览到 InterSystems.Data.IRISClient.dll 文件的位置。 选择文件并点击 Add(添加)。 点击 OK(確定)。 在 Visual Studio Solution Explorer 中, InterSystems.Data.IRISClient.dll 程序集现在应该列在 Reference(引用)下。 使用 IRIS Native 现在,您已经准备好实验 IRIS Native 了。打开在创建 Visual Studio 项目时创建的文件(例如,Program.cs)。删除文件的默认内容并粘贴以下代码,用您的 InterSystems IRIS 实例的连接信息替换 conn.ConnectionString 中的值。(logfile 的值必须是本地系统上的可写路径)。您可以指定所示的 USER命名空间,也可以选择在实例上创建另一个命名空间。 using System; using InterSystems.Data.IRISClient; using InterSystems.Data.IRISClient.ADO; public class IRISNative { public static void Main(String[] args) { try { // open connection to InterSystems IRIS instance using connection string IRISConnection conn = new IRISConnection(); // edit this ConnectionString to match your environment conn.ConnectionString = "Server=localhost; Port=1972; Namespace=User; Password=SYS; User ID=_system; logfile=c:\\sandbox\\dbnative.log"; conn.Open(); // create IRIS Native object IRIS iris = IRIS.CreateIRIS(conn); Console.WriteLine("[1. Setting and getting a global]"); // setting and getting a global // ObjectScript equivalent: set ^testglobal("1") = 8888 iris.Set(8888, "^testglobal", "1"); // ObjectScript equivalent: set globalValue = $get(^testglobal("1")) Int16? globalValue = iris.GetInt16("^testglobal", "1"); Console.WriteLine("The value of ^testglobal(1) is " + globalValue); Console.WriteLine(); Console.WriteLine("[2. Iterating over a global]"); // modify global to iterate over // ObjectScript equivalent: set ^testglobal("1") = 8888 // ObjectScript equivalent: set ^testglobal("2") = 9999 iris.Set(8888, "^testglobal", "1"); iris.Set(9999, "^testglobal", "2"); // iterate over all nodes forwards Console.WriteLine("walk forwards"); IRISIterator subscriptIter = iris.GetIRISIterator("^testglobal"); foreach (var node in subscriptIter) { Console.WriteLine("subscript=" + subscriptIter.CurrentSubscript + ", value=" + node); } Console.WriteLine(); Console.WriteLine("[3. Calling a class method]"); // calling a class method // ObjectScript equivalent: set returnValue = ##class(%Library.Utility).Date(5) String returnValue = iris.ClassMethodString("%Library.Utility", "Date", 5); Console.WriteLine(returnValue); Console.WriteLine(); // close IRIS object and connection iris.Close(); conn.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }}} 示例代码分为三个部分: 第一部分展示了如何设置一个 global 的值以及稍后如何检索它。这部分里面执行的命令等同于 ObjectScript 的 SET 和 GET 命令。 第二部分展示了如何迭代 global 的子节点,类似于ObjectScript中的 $ORDER函数。 第三部分展示了如何使用 IRIS Native 从您的 .NET 应用程序调用 ObjectScript 类方法。 如果您使用的是本地安装的实例,并且因此连接使用 localhost 作为服务器地址,那么程序可能使用本地共享内存连接,这比标准的 TCP/IP 连接还要快。 注意: ObjectScript 中的 Globals 以插入符号(^)开头。在使用 InterSystems IRIS Native API 的 .NET 应用程序中,这不是必需的。 运行练习 现在可以按 Ctrl+F5 运行演示应用程序了。如果示例执行成功,您应该会看到带有示例代码结果的打印输出: [1. Setting and getting a global] The value of ^testglobal(1) is 8888 [2. Iterating over a global] walk forwards subscript=1, value=8888 subscript=2, value=9999 [3. Calling a class method] Oct 30, 2018 在管理门户(Management Portal)中确认变更 接下来,使用以下程序在管理门户(Management Portal)中确认您的结果: 使用InterSystems IRIS 基础:连接一个 IDE中为您的实例描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 如果您不在代码指定的命名空间中,请切换到该命名空间。 导航到 Globals 页面(System Explorer(系统资源管理器) > Global)。您应该会看到在示例代码中创建的 testglobal。点击 VIEW 来查看其内容。 您应该会看到 global 的两个节点:^testglobal(1) = 8888 和 ^testglobal(2) = 9999。 了解有关 IRIS Native 的更多信息 有关 IRIS Native、globals 和 InterSystems IRIS 的更多信息,请参见: 用于.Net的 Native API 技术概要:用于Java的 InterSystems IRIS Native API 使用 Globals 用于.NET 的 InterSystems Managed Provider
文章
Louis Lu · 九月 26, 2021

IRIS 2021 技术文档 First Look 10 -- InterSystems .Net 网关

本技术概要( First Look)通过重点概述和一个基础的、实际操作的示例,向您介绍在 InterSystems IRIS®数据平台上使用 .NET 网关(Gateway)的基础知识。您将了解 InterSystems IRIS 如何与 .NET 程序集进行互操作,在这个示例中,您将创建一个 .NET 网关(Gateway),并从 InterSystems IRIS 中的代理类调用基础 DLL。 本文档设计简单;当您把 .NET 网关(Gateway)引入您的生产系统时,您可能需要做一些不同的事情。本文档末尾的参考资料,提供了有关在生产中使用 .NET 网关(Gateway)的详细和完整的信息。 要浏览所有的技术概要(First Look),包括其他可以在免费的云实例或 web 实例上执行的技术概要(First Look),请参见 InterSystems First Looks(InterSystems 技术概要)。 1. 为什么 .NET 网关(Gateway)很重要 InterSystems IRIS Object Gateway for .NET(也称为".NET 网关(Gateway)")为InterSystems IRIS 与 Microsoft .NET Framework 组件进行互操作提供了一种简便的方法。在使用网关(Gateway)导入 .NET DLL 后,您可以实例化一个外部 .NET 对象,InterSystems IRIS通过代理类将其作为的一个本地对象来操作。 每个代理对象(proxy object)都与相应的 .NET 对象通信,使您能够从 InterSystems IRIS 和 ObjectScript 中访问您的 .NET 类和方法。调用任何 InterSystems IRIS 代理方法都会将消息发送给 .NET 网关(Gateway) 工作线程,该线程会找到合适的方法或构造函数调用。调用的结果发送回代理对象,再将结果返回给 InterSystems IRIS 应用程序。 通常,使用 .NET 网关(Gateway)的最佳方法是在您的应用程序中为第三方 DLL 构建一个小型包装器类(a small wrapper class),然后为包装器生成代理类。包装器类只公开您想要的功能,而不是创建大量应用程序可能不需要的代理类。 2. 探索 .NET 网关(Gateway) 在这个实际操作的示例中,您将: 创建一个 DLL,其中包含要从 InterSystems IRIS 调用的示例类 定义一个 .NET 网关(Gateway),并启动服务器进程 创建一个 ObjectScript 类,从 DLL 生成代理类 创建另一个 ObjectScript 类,以连接到网关(Gateway)并通过代理对象操作 DLL 想试试 InterSystems IRIS .NET 开发和互操作性功能的在线视频演示吗?请看.NET QuickStart(.NET 快速入门)! 2.1 用前须知 要运行这个演示,您需要一个运行 Microsoft .NET Framework 4.5 版本 的 Windows 10 系统、Visual Studio,以及一个已安装的 InterSystems IRIS 实例。(有关安装 InterSystems IRIS 的说明,请参见 InterSystems IRIS Basics:Installation [《InterSystems IRIS 基础:安装》]。) 有关配置 Visual Studio 以连接到您的 InterSystems IRIS 实例的说明,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE。 您还将使用InterSystems 的 Studio IDE(一个在 Windows 系统上运行的客户端应用程序)来创建 ObjectScript 代码;更多信息,请参见InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 Using Studio(使用 Studio) 和 Studio。 )​​​​​​ 2.2 创建 DLL 使用 Visual Studio,创建一个名为 Person 的类并复制以下 C# 代码。在本例中使用 .NET 4.5。 public class Person { public int age; public String name; //constructor public Person (int startAge, String Name) { age = startAge; name = Name; } public void setAge(int newAge) { age = newAge; } public String getName() { return name; } public int getAge() { return age; } public static void main(String []args) { Person myPerson = new Person (5, "Tom"); Console.Out.WriteLine(myPerson.getName()); Console.Out.WriteLine(myPerson.getAge()); } } 编译 Person 类,并生成一个 Person.dll 文件。注意 DLL 的位置,因为您稍后会需要它。 2.3 创建并启动 .NET 网关 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 导航至 System Administration(系统管理) > Configuration(配置) > Connectivity(连接) > External Language Servers(外部语言服务)。 选择 Create External Language Server(创建外部语言服务)。 输入 Server Name(网关名称)。 在 Server Type (服务类型)中选择 .Net 在 Port(端口)字段中,输入 55000。 对于 .NET Version(.NET 版本),请选择 4.5。 选择 Save(保存)。 在External Language Servers(外部语言服务)页面,找到您刚刚定义的网关(Gateway),并选择 Start(开始) 2.4 生成代理类 使用 Studio, 在实例的 USER 命名空间中创建一个名为 CreateProxyClasses.cls 的新 ObjectScript 类,并粘贴以下代码, 将您的实例的主机标识符替换为 gwyConn.%Connect 中的 server,并用双引号括起来的 Person.dll 文件的完整文件路径替换 YOUR FILEPATH HERE。 Class User.CreateProxyClasses Extends %Persistent { ClassMethod run() { // get a connection to the .NET Gateway set gwyConn = ##class(%Net.Remote.Gateway).%New() set status = gwyConn.%Connect("127.0.0.1", 55000, "USER") if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // add the DLL to the classpath set classpath = ##class(%ListOfDataTypes).%New() do classpath.Insert("YOUR FILEPATH HERE") set status = gwyConn.%AddToCurrentClassPath(classpath) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // create the proxy ObjectScript classes corresponding to the .NET classes in the DLL set status = gwyConn.%Import("Person",,,,1) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } //close the connection to the .NET Gateway set status = gwyConn.%Disconnect() if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } } } 编译并构建该类。然后使用 InterSystems IRIS Basics:Connecting an IDE(InterSystems IRIS 基础: 连接一个 IDE) 中的 instructions for your instance(对您的实例的说明),在 USER 命名空间中打开 InterSystems 终端(InterSystems Terminal), 并执行以下命令: do ##class(User.CreateProxyClasses).run() 2.5 使用ObjectScript 操作 .NET Object 在 USER 命名空间中创建另一个名为 ManipulateObjects.cls 的 ObjectScript 类,并粘贴以下代码 (注意要将您的实例的主机标识符替换 gwyConn.%Connect 中的 第一个参数): Class User.ManipulateObjects Extends %Persistent { ClassMethod run() { // get a connection to the .NET gateway set gwyConn = ##class(%Net.Remote.Gateway).%New() set status = gwyConn.%Connect("127.0.0.1", 55000, "USER") if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // manipulate some proxy objects set person = ##class(User.Person).%New(gwyConn,5,"Tom") write !,"Name: "_person.getName() write !,"Age: "_person.getAge() do person.setAge(100) write !,"Age: "_person.getAge() // close the connection to the .NET gateway set status = gwyConn.%Disconnect() if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } } } 编译并构建该类,然后在终端(Terminal)中的 USER 命名空间中执行以下命令: do ##class(User.ManipulateObjects).run() 您应该可以看到以下输出: Name: Tom Age: 5 setting age to 100 Age: 100 现在您已经成功地完成了练习,停止您创建的 .NET 网关(Gateway)。返回到管理门户(Management Portal)中的 External Language Servers(外部语言服务)页面,找到网关(Gateway),并选择 Stop(停止)。 3. 了解更多有关 .NET 网关(Gateway)的信息 从这里,您可以继续探索 .NET 网关(Gateway)和 InterSystems IRIS。请参阅下面的文档和参考资料,了解 .NET、互操作性、应用程序开发等。 Using the Gateway for .NET(使用 .NET 网关) — 了解更多有关 InterSystems IRIS 和 Microsoft .NET Framework 组件之间互操作性的信息。 Skyrocket Your .NET Application Development(Skyrocket Your .NET 应用程序开发) — 这是 InterSystems 关于在 .NET 中作为对象建模和访问数据的演示。 .NET Documentation(.NET 文档) — Microsoft 在 .NET 上的文档,包括架构概念、教程和开发指南。
文章
jieliang liu · 九月 23, 2021

IRIS 2021 技术文档 First Look 19 使用 InterSystems 产品优化 SQL 性能

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix { height: auto; margin-top: 16px; margin-bottom: 16px; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } .md-inline-math-container mjx-container { zoom: 0.95; } .CodeMirror { height: auto; } .CodeMirror.cm-s-inner { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-scroll { overflow: auto hidden; z-index: 3; } .CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); } .CodeMirror-gutters { border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; white-space: nowrap; background-position: inherit; background-repeat: inherit; } .CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); } .cm-s-inner .cm-keyword { color: rgb(119, 0, 136); } .cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); } .cm-s-inner .cm-number { color: rgb(17, 102, 68); } .cm-s-inner .cm-def { color: rgb(0, 0, 255); } .cm-s-inner .cm-variable { color: rgb(0, 0, 0); } .cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); } .cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); } .cm-s-inner .cm-string { color: rgb(170, 17, 17); } .cm-s-inner .cm-property { color: rgb(0, 0, 0); } .cm-s-inner .cm-operator { color: rgb(152, 26, 26); } .cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); } .cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); } .cm-s-inner .cm-meta { color: rgb(85, 85, 85); } .cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); } .cm-s-inner .cm-builtin { color: rgb(51, 0, 170); } .cm-s-inner .cm-bracket { color: rgb(153, 153, 119); } .cm-s-inner .cm-tag { color: rgb(17, 119, 0); } .cm-s-inner .cm-attribute { color: rgb(0, 0, 204); } .cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); } .cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); } .cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); } .cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); } .cm-negative { color: rgb(221, 68, 68); } .cm-positive { color: rgb(34, 153, 34); } .cm-header, .cm-strong { font-weight: 700; } .cm-del { text-decoration: line-through; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-error { color: red; } .cm-invalidchar { color: red; } .cm-constant { color: rgb(38, 139, 210); } .cm-defined { color: rgb(181, 137, 0); } div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); } .cm-s-inner .CodeMirror-activeline-background { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror { position: relative; overflow: hidden; } .CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-sizer { position: relative; } .CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; } .CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; } .CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; } .CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; } .CodeMirror-gutter-filler { left: 0px; bottom: 0px; } .CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; } .CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; border: none !important; background-position: 0px 0px !important; } .CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-lines { cursor: text; } .CodeMirror pre { border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-width: 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; background-position: 0px 0px; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-code pre { border-right-width: 30px; border-right-style: solid; border-right-color: transparent; width: fit-content; } .CodeMirror-wrap .CodeMirror-code pre { border-right-style: none; width: auto; } .CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; } .CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; } .CodeMirror-measure pre { position: static; } .CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right-style: none; width: 0px; } .CodeMirror div.CodeMirror-cursor { visibility: hidden; } .CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; } .cm-searching { background-color: rgba(255, 255, 0, 0.4); } span.cm-underlined { text-decoration: underline; } span.cm-strikethrough { text-decoration: line-through; } .cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); } .cm-tw-deleted { text-decoration: line-through; } .cm-tw-header5 { font-weight: 700; } .cm-tw-listitem:first-child { padding-left: 10px; } .cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; } .cm-tw-underline { text-decoration: underline; } @media print { .CodeMirror div.CodeMirror-cursor { visibility: hidden; } } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; -webkit-font-smoothing: antialiased; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 技术概要:使用 InterSystems 产品优化 SQL 性能使用 InterSystems SQL 优化查询使用 EXPLAIN 关键字显示查询计划在管理门户(Management Portal)中使用 SQL 查询接口显示查询计划发现查询计划结果中潜在的性能问题测试查询执行测试位片索引(Bitslice Index)的效果向交易类型字段(TransactionType Field)添加位图索引(Bitmap Index)重新测试查询性能查看随时间变化的查询性能了解有关 InterSystems SQL 的更多信息介绍材料 技术概要:使用 InterSystems 产品优化 SQL 性能 技术概要:使用 InterSystems 产品优化 SQL 性能 本技术概要(First Look)指南向您介绍了 InterSystems SQL 查询优化,包括查询分析工具的使用,几种索引方法以及随着时间的变化查看运行时统计数据的能力。 要浏览所有的技术概要(First Look),包括其他可以在免费的云实例或 web 实例上执行的技术概要(First Look),请参见 InterSystems First Looks(《InterSystems 技术概要》)。 使用 InterSystems SQL 优化查询 InterSystems IRIS®数据平台为 SQL 查询性能调整提供全套工具: 查询计划分析的图形化显示 如位图和位片索引(bitslice index)等索引策略结构紧凑,可由矢量化 CPU 指令有效处理。每种索引类型都为某些查询类型(如逻辑条件、计数和聚合函数)提供了好处。通过索引,您可以在一个核心上实现每秒多达数十亿行的查询性能结果。 随时间变化的 SQL 查询性能指标 重要提示: 下面演示中显示的查询性能数字代表了在一台 Windows 10 笔记本电脑上进行的多次演示试验。根据您的环境,您可能会看到不同的查询性能数字。 想查看 InterSystems IRIS SQL 功能快速演示吗?请查看 SQL QuickStart(SQL 快速入门)! 用前须知 阅读本文之前,建议阅读并完成 First Look:InterSystems SQL(《技术概要:InterSystems SQL》)。在这里,您将再次使用 InterSystems IRIS SQL Shell;您将使用的数据来自您在技术概要:InterSystems SQL的演示时创建的百万记录股票交易数据表。 您还将运行 TuneTableutility,它检查表中的数据并创建 InterSystems SQL 查询优化器(决定如何最好地运行任何查询的引擎)使用的统计数据。这些统计数据包括表的大小(区段大小)和每列唯一值的数量(选择性)。优化器在决定连接顺序等情况下使用表大小,其中最好从较小的表开始。在表有多个索引的情况下,选择性有助于优化器选择最佳索引。在产品实例中,您通常只运行一次 TuneTable:在数据被加载到表中之后和运行之前。 演示:显示和解释优化前的查询计划 First Look:InterSystems SQL (《技术概要:InterSystems SQL》)解释了如何执行在技术概要(First Look)和此处运行演示所需的以下步骤: 选择一个 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;关于如何部署每种类型的信息,请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 打开 InterSystems 终端(Terminal)(简称终端(Terminal))来运行 SQL Shell。 从 GitHub repo https://github.com/intersystems/FirstLook-SQLBasics 获取本指南的实用程序文件和数据,包括 stock_table_demo_two.csv,其中包含一百万行股票表数据 Loader.xml,是一个包含实用程序方法的类文件,用于将 Stock_table_demo_two.csv 中的数据加载到InterSystems IRIS 表中。 运行 TuneTable 实用程序 如果您的 InterSystems IRIS 实例不再包含 StockTableDemoTwotable,请按照 Demo:Using Bitmap Indexing To Maximize Query Performance(《演示:使用位图索引最大化查询性能》)(在执行 SELECT DISTINCT 查询之前停止)的前四个步骤重新创建并加载它。 在 SQL Shell 中,在 FirstLook.StockTableDemoTwo 上运行 TuneTable 实用程序,如下所示: OBJ DO $SYSTEM.SQL.TuneTable("FirstLook.StockTableDemoTwo") 该命令在 SQL Shell 中不会生成可见的输出。 使用 EXPLAIN 关键字显示查询计划 这个演示假设您想获得所有"SELL"交易的平均价格。鉴于该表包含一百万条记录,所需的查询有可能非常慢。 虽然您可能已经想在 Price 和 TransactionType 字段上创建索引,但在开始优化工作之前,查看查询计划将具有指导意义。在 SQL Shell 中,您可以通过在查询前添加 EXPLAIN 关键字来显示查询计划。查询计划显示 SQL 查询优化器将如何使用索引(如果有索引的话),或者是否将直接读取表数据来执行语句。 要使用 EXPLAIN 关键字来显示查询计划,在 SQL Shell 中执行以下语句: EXPLAIN SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' 这将返回格式为 XML 的查询计划: xxxxxxxxxx Plan "<plans> <plan> <sql> SELECT AVG ( Price ) AS AveragePrice FROM FirstLook . StockTableDemoTwo WHERE TransactionType = ? /*#OPTIONS {""DynamicSQLTypeList"":""1""} */ </sql> <cost value=""1827000""/> Call module B. Output the row. <module name=""B"" top=""1""> Process query in parallel, partitioning master map FirstLook.StockTableDemoTwo.IDKEY into subranges of T1.ID values, piping results to temp-file A: SELECT count(T1.Price),sum(T1.Price) FROM %NOPARALLEL FirstLook.StockTableDemoTwo T1 where ((%SQLUPPER(T1.TransactionType) = %SQLUPPER(?))) Read temp-file A, looping on a counter. For each row: Accumulate the count([value]). Accumulate the sum([value]). </module> 演示:显示和解释优化前的查询计划 </plan> <plan> <sql> SELECT COUNT ( T1 . Price ) , SUM ( T1 . Price ) FROM %NOPARALLEL FirstLook . StockTableDemoTwo T1 WHERE ( ( %SQLUPPER ( T1 . TransactionType ) = %SQLUPPER ( ? ) ) ) %PARTITION BY T1 . ID > ? AND T1 . ID <= ? </sql> <cost value=""1827000""/> Call module B. Output the row. <module name=""B"" top=""1""> Read master map FirstLook.StockTableDemoTwo.IDKEY, looping on ID (with a range condition). For each row: Accumulate the count(Price). Accumulate the sum(Price). </module> </plan> </plans>" 您将看到为执行 SQL 查询而生成的查询计划可以分为多个模块,每个模块都执行计划的不同部分,例如评估子查询。 实际上,这个查询计划被分为两个独立的计划。顶部计划用于初始查询。它调用一个模块 B,在这个模块中,其中"主映射"被分区,并在每个分区上并行执行子查询。子查询的计划遵循初始查询的计划。 在 "Spotting Potential Performance Issues in Query Plan Results(在查询计划结果中发现潜在的性能问题)"中,您将学习如何识别这个查询的问题。 在管理门户(Management Portal)中使用 SQL 查询接口显示查询计划 InterSystems IRIS 在管理门户(Management Portal)中提供了一个基于 web 的接口,用于 SQL 查询执行和计划分析。要使用管理门户(Management Portal)中的 SQL 查询接口显示查询计划: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在浏览器中打开您的实例的管理门户(Management Portal)。 请确保您是在 USER 命名空间。 如果您还没有找到,可以: 在屏幕的顶部面板中,点击当前命名空间名称右侧的 SWITCH(交换)。 在弹出的窗口中,选择 USER(用户) 并点击 OK(确定)。 导航到 SQL 页面(System Explorer(系统资源管理器) > SQL)。 省略 EXPLAIN 关键字,将"Using the EXPLAIN Keyword to Show a Query Plan(使用 EXPLAIN 关键字显示查询计划)中的查询粘贴到 Execute Query(执行查询) 标签的文本字段中。 点击 Show Plan(显示计划) 来显示查询计划。 结果将如下所示: 解释这些结果是下一节的主题。 发现查询计划结果中潜在的性能问题 查看查询计划结果,您可以看到这个查询存在一些严重的潜在性能问题。如果您查看子查询的计划,也就是实际工作完成的地方,您可以看到第一个任务是 "读取主映射"。这意味着 InterSystems SQL 查询优化器不会使用任何索引来运行查询; 演示:测试查询优化 相反,查询将遍历表中的所有 ID。特别是在大表的情况下,这表明查询将不能很好地执行。 当您优化查询时,您会看到它的执行时间减少,查询计划也会有明显的变化。 注意: 相对成本可以很好地预测性能,但只是相对于某个特定的查询而言。如果您在表中添加了一个索引,并且看到相对成本下降了,那么很可能这个查询现在会运行得更快。然而,相对成本并不是为了比较两个不同查询的性能。 测试查询执行 要获取有关未优化查询将如何执行的一些实际数据,请在 SQL Shell 中运行它: SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO 输出将如下所示: xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0009s/6/1246/0ms execute time(s)/globals/cmds/disk: 0.2599s/1000075/8502571/0ms cached query class: %sqlcq.USER.cls5 语句准备和执行指标分别列出。特别注意以下两项: 执行时间为 0.2599 秒。虽然这个时间看起来并不算长,但可以通过使用索引大大改善。 在执行步骤中读取的 globals 数量为 1,000,075。(Globals 是 InterSystems IRIS 用来存储数据的多维稀疏数组(multidimensional sparse arrays);更多信息,请参见 Introduction to InterSystems IRIS Programming(《InterSystems IRIS 编程简介》)中的Introduction to Globals(Globals 简介)一章。为了提高查询性能,应该减少这个数字。您会在下一节看到这种情况。 重要提示: 准备工作只需一次:第一次重新规划查询。如果修改了相关表或添加或删除了索引,查询将自动重新规划。大多数应用程序只准备一次查询,但会多次执行。因此,在这个演示中,我们的重点将是调整执行性能。 演示:测试查询优化 向价格字段添加位片索引(Bitslice Index) 如果您的查询将包含一个或多个字段上的聚合函数,那么为这些字段中的一个或多个字段添加位片索引(bitslice index)可能会提高性能。 位片索引(bitslice index)将字段中的每个数字数据值表示为二进制位字符串,二进制值中的每个数字都有一个位图,以记录哪些行的二进制数字为 1。 因为我们想要获得所有"SELL"交易的平均价格,所以在 Price 字段中添加一个位片索引(bitslice index)是有意义的。要在 Price 字段上创建位片索引(bitslice index) PriceIdx,请在 SQL Shell 中执行以下语句: 演示:测试查询优化 CREATE BITSLICE INDEX PriceIdx ON TABLE FirstLook.StockTableDemoTwo (Price) CREATE BITSLICE INDEX PriceIdx ON TABLE FirstLook.StockTableDemoTwo (Price) xxxxxxxxxx 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0091s/2000/13151/0ms execute time(s)/globals/cmds/disk: 1.4268s/2087789/55765062/1ms cached query class: %sqlcq.USER.cls7 但是,正如您将在下面看到的,仅仅因为您创建了索引并不一定意味着 InterSystems SQL 查询优化器会使用它 。 测试位片索引(Bitslice Index)的效果 要查看新的位片索引(bitslice index)是否会对查询的执行方式或运行速度产生任何影响,请使用上述任何一种方法(SQL Shell 或管理门户(Management Portal))来显示查询计划。 正如您将看到的,查询计划仍然与以前相同。InterSystems SQL 查询优化器将不会使用新的索引。 运行查询产生的性能统计数据与您创建位片索引(bitslice index)之前几乎相同(0.2559 秒的执行时间与 0.2599 秒相比)。InterSystems IRIS 智能地缓存查询计划和数据,因此同一查询的后续运行可能会提高性能,鉴于查询性能时间略有不同,这里可能就是这种情况。 在机器上运行的其他应用程序也会影响性能。 SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0569s/35431/227191/0ms execute time(s)/globals/cmds/disk: 0.2559s/1000075/8502571/0ms cached query class: %sqlcq.USER.cls8 如果从查询中删除 WHERE 子句,当您显示查询计划时,将会看到完全不同的结果: 如您所见,读取位片索引(bitslice index)是查询计划的第一步。在这个计划中没有读取到"总映射"。 SQL 查询优化器也使用第二个索引 FirstLook.StockTableDemoTwo.$StockTableDemoTwo。这是位图范围索引, 在执行 CREATE TABLESQL 语句时自动创建。它是表中所有行的位图索引(bitmap index),而不仅仅是一个字段,每个位的值反映了该行是否实际存在。 演示:测试查询优化 然而,我们真正想要运行的查询包含一个 WHERE 子句。因此,我们必须找到一种方法,让 SQL 查询优化器在 WHERE 子句存在时使用索引。 向交易类型字段(TransactionType Field)添加位图索引(Bitmap Index) 如果您阅读了 InterSystems SQL Optimization Guide(《InterSystems SQL 优化指南》),您会发现 InterSystems SQL 查询优化器在与 WHERE 子句字段上的位图索引(bitmap index)结合使用时,通常会使用位片索引(bitslice index)。 这是因为没有 WHERE 子句的聚合查询可以简单地聚合索引中的所有数据。然而,为了只聚合满足 WHERE 条件的行,查询必须掩码那些不满足条件的行的位片索引(bitslice index)的位。在 WHERE 子句中的字段上有一个位图索引(bitmap index),允许有效地构建这个掩码。 幸运的是,查询中的另一个字段 TransactionType 是位图索引(bitmap index)的一个很好的候选者,因为它的可能值计数是两个("SELL"和"BUY")。 要向 TransactionType 字段添加位图索引(bitmap index),请在 SQL Shell 中执行以下语句: CREATE BITMAP INDEX TransactionTypeIdx ON TABLE FirstLook.StockTableDemoTwo (TransactionType) CREATE BITMAP INDEX TransactionTypeIdx ON TABLE FirstLook.StockTableDemoTwo (TransactionType) xxxxxxxxxx 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0069s/2001/13291/0ms execute time(s)/globals/cmds/disk: 1.1046s/2088960/19771584/0ms cached query class: %sqlcq.USER.cls7 重新测试查询性能 现在,您已经添加了位片索引(bitslice index)和位图索引(bitmap index):如果您显示的查询计划 SELECT AVG(Price) as AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' 在 SQL Shell 或管理门户(Management Portal)中,您会看到查询优化器使用您创建的两个索引来获得最佳性能。 还请注意,18742 的相对成本只是未优化查询的一小部分,其成本为 1827000。 演示:测试查询优化 最后,如果您在 SQL Shell 中运行这个查询,您会看到对 globals 的更有效使用(594 而不是 1000075)。 最关键的是,有索引的查询运行速度比无索引的查询快了近 85 倍(执行时间为 0.0031 秒,而非 0.2599)。 查看随时间变化的查询性能 SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0554s/34877/186130/0ms execute time(s)/globals/cmds/disk: 0.0031s/594/2878/0ms cached query class: %sqlcq.USER.cls8 为了随时间跟踪查询的性能,InterSystems IRIS 提供了查询统计数据,您将在下一节了解如何查看这些数据。 查看随时间变化的查询性能 要跟踪运行缓慢的查询或查看新查询在产品中的运行情况,您可以使用管理门户(Management Portal)中的 SQL Statements(SQL 语句)视图。要导航到这个视图,在管理门户(Management Portal)中打开 SQL 查询接口,并点击 SQL Statements(SQL语句)。 例如,如果您上面调整的查询在其原始(未优化的)计划下运行了 9 次,您可能会看到类似这样的结果: 点击 SQL Statement Text column(SQL 语句文本列)中的语句链接, 允许您以 SQL 形式查看查询: 您还可以使用缓存查询类的名称将 SQL 语句执行与 SQL Statements(SQL 语句)视图联系起来,该名称是 SQL Shell 中输出的最后一行,并列在 SQL Statements(SQL 语句) 的 Location(s)(位置)列中。 在您优化查询并运行几次后,您可以期望看到 Total time(总时间)和 Average time(平均时间)的改善列。 了解有关 InterSystems SQL 的更多信息 请注意,Count(计数)的值已经下降。这是因为位图和位片索引(bitslice index)的添加引起了查询计划的改变,这反过来又触发了对相关类的缓存查询的删除。该查询在新查询计划下总共运行了 8 次,平均每天 4 次。 了解有关 InterSystems SQL 的更多信息 要了解更多有关 SQL 和 InterSystems IRIS 的信息,请参见: 介绍材料 First Look:InterSystems SQL(《技术概要:InterSystems SQL》) Using InterSystems SQL(《使用 InterSystems SQL》) InterSystems SQL Reference(《InterSystems SQL 参考书目》) InterSystems SQL Overview(《InterSystems SQL 概述》) SQL 开发 SQL -- Things You Should Know(《SQL -- 您应该知道的事情》) Developing with InterSystems Objects and SQL(《使用 InterSystems Objects 和 SQL 开发》) 查询优化 InterSystems SQL Optimization Guide(《InterSystems SQL 优化指南》) Optimizing SQL Queries(《优化 SQL 查询》) 分片和可扩展性 First Look:Scaling for Data Volume with Sharding(《技术概要:带分片的数据卷扩展》) Scalability Guide(《可扩展性指南》) SQL 搜索 First Look:SQL Search with InterSystems IRIS(《技术概要:使用 InterSystems IRIS 进行 SQL 搜索》) Using InterSystems SQL Search(《使用 InterSystems SQL 搜索》) Creating iFind Indices for Searching Text Fields(《创建用于搜索文本字段的 iFind 索引》) JDBC First Look:JDBC and InterSystems IRIS (《技术概要:JDBC 和 InterSystems IRIS》) Using Java JDBC with InterSystems IRIS(《在 InterSystems IRIS 中使用 Java JDBC》)<文档> Java Overview (《Java 概述》) 了解有关 InterSystems SQL 的更多信息 Using JDBC with InterSystems IRIS(《在 InterSystems IRIS 中使用 JDBC》) <在线学习>
文章
Nicky Zhu · 九月 22, 2021

IRIS 2021 技术文档 First Look 7 -- 技术概要: 数据转换

本文档将帮助您使用 InterSystems IRIS®数据平台集成产品转换数据。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些, 请参见 InterSystems First Looks(《InterSystems 技术概要》)。 数据转换和互操作性 数据转换是 InterSystems IRIS 互操作性的核心。您可以改变从一个系统传入的数据的格式和内容,以满足下游系统的要求,从而允许系统之间进行通信。简单地说,从一个系统发送的信息可以转换为另一个应用程序可以理解的信息。使用 InterSystems IRIS,可以很容易地进行数据转换的创建、测试和维护。 假设您有两个包含产品价格的零售系统。当系统 A 向其他系统发送数据时,包含了不加税的产品基准价格。但是,系统 B 需要在价格中包含地区税。InterSystems IRIS 互操作性产品中的数据转换可以在将数据发送到系统 B 之前将从系统 A 收到的价格转换为加税价格。一旦定义,数据转换将自动处理修改。 常见的转换包括: 将值(value)从源信息复制到目标信息。 根据源信息的(value)执行计算,并将结果复制到目标信息。 为目标信息分配新的值(literal value)。 重新排列数据的顺序。 探索 DTL 编辑器 您可以编写 DTL(数据转换语言)代码来创建数据转换,也可以使用 DTL 编辑器(DTL Editor)来创建。DTL 编辑器(DTL Editor)允许非技术用户无需编写代码就可以创建数据转换。例如,它的图形用户界面允许您通过拖放操作快速地将值从源信息映射到目标信息。下面的 DTL 编辑器(DTL Editor)之旅将通过在产品中创建数据转换来指导您了解其主要功能。有关 InterSystems IRIS 产品的介绍,请参见 First Look:Connecting Systems Using Interoperability Productions(《技术概要:使用互操作性产品连接系统》)。 在这个演示中,必须转换班级里学生的期末成绩数据,以便不同的应用程序可以使用这些数据。 想试试 InterSystems IRIS 互操作性功能的在线视频演示吗?请查看 Interoperability QuickStart(互操作性快速入门)! 用前须知 在开始使用 DTL 编辑器(DTL Editor)之前,您需要完成以下工作: 选择一个 InterSystems IRIS 实例。 从 GitHub 下载 InterSystems IRIS 产品和示例文件。 创建一个支持互操作性的命名空间。 将下载的产品导入命名空间. 选择 InterSystems IRIS 实例 要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。有关如何部署每种类型的实例的信息(如果您还没有可使用的实例) 请参见 InterSystems IRIS Basics: Connecting an IDE(InterSystems IRIS 基础:连接一个 IDE)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 从 GitHub 下载 从 https://github.com/intersystems/FirstLook-Data- Transformations 中下载本演示所使用的产品和数据文件。XML 文件是即将部署在系统上的 InterSystems IRIS 产品的载体,您可以通过XML文件导入或导出Production代码。 实例必须可以访问技术概要-数据转换(FirstLook-DataTransformations) 源。下载文件的程序取决于您所使用的实例类型,如下所示: 如果您使用的是 ICM 部署的实例: 使用带有-machine 和 -interactive 选项的 icm ssh 命令,在托管实例的节点上打开默认 shell,例如: icm ssh -machine MYIRIS-AM-TEST-0004 -interactive 在 Linux 命令行上,使用以下命令之一将 repo 克隆到实例的数据存储卷(data storage volume)。例如,对于部署在 Azure 上的配置,数据卷的默认挂载点(default mount point)是 /dev/sdd,因此您可以使用如下命令: $ git clone https://github.com/intersystems/FirstLook-DataTransformations /dev/sdd/FirstLook-DataTransformations OR $ wget -qO- https://github.com/intersystems/FirstLook-DataTransformations/archive/master.tar.gz | tar xvz -C /dev/sdd 这些文件现在对容器文件系统上 /irissys/data/FirstLook-DataTransformations 中的 InterSystems IRIS 可用。 如果您正在使用通过其他方式部署的容器化实例(授权版或社区版[Community Edition]): 在主机上打开 Linux 命令行。(如果您在云节点上使用社区版[Community Edition]),请使用 SSH 连接该节点,如在 Deploy and Explore InterSystems IRIS[《部署和探索 InterSystems IRIS》] 中所述。) 在 Linux 命令行上,使用 git clone 或 wget 命令,如上所述,将 repo 克隆到容器中挂载为卷的存储位置。 - 对于社区版(Community Edition)实例,您可以克隆到实例的持久化 %SYS 目录 (存储特定于实例的配置数据的目录)。在 Linux 文件系统中,这个目录是 /opt/ISC/dur。这使得文件对容器文件系统上 /ISC/dur/FirstLook-DataTransformations 中的 InterSystems IRIS 可用。 - 对于已授权的容器化实例,选择容器中作为卷挂载的任何存储位置(如果使用它,包括持久化 %SYS 目录)。例如,如果您的 docker run 命令包含选项 -v /home/user1:/external, 并且您将 repo 克隆到 /home/user1,则文件对容器文件系统上 /external/FirstLook-DataTransformations 中的 InterSystems IRIS 可用。 如果您使用的是 InterSystems 学习实验室(Learning Labs)实例: 在集成 IDE 中打开命令行终端。 将目录更改为 /home/project/shared 并使用 git clone 命令克隆 repo: $ git clone https://github.com/intersystems/FirstLook-DataTransformations 该文件夹被添加到左边资源管理器(Explorer)面板的 Shared (共享)下,并且该目录对 /home/project/shared 中的 InterSystems IRIS 可用。 如果您使用的是已安装的实例: 如果实例的主机是安装了 GitHub 桌面(GitHub Desktop)和 GitHub 大文件存储(GitHub Large File Storage)的 Windows 系统: 在主机的 web 浏览器中进入 https://github.com/intersystems/FirstLook-DataTransformations。 选择 Clone or download(克隆或下载) 然后选择 Open in Desktop(在桌面上打开)。 这些文件对您的 GitHub 目录中的 InterSystems IRIS 可用,例如在 C:\Users\User1\Documents\GitHub\FirstLook-DataTransformations 中。 如果主机是 Linux 系统, 只需在 Linux 命令行上使用 git clone 命令或 wget 命令将 repo 克隆到您所选择的位置。 创建一个支持互操作性的命名空间 在导入从 GitHub 下载的产品之前,您必须创建一个支持互操作性的命名空间。如果您已经在实例上创建了一个支持互操作性的命名空间,您可以将它用于此产品。要创建一个新的支持互操作性的命名空间,请使用以下过程。(您首次安装 InterSystems IRIS 时创建的命名空间不支持互操作性)。 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(实例适用的URL),在浏览器中打开您的实例的管理门户(Management Portal)。 选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间),进入 Namespaces(命名空间) 页面。 在 Namespaces (命名空间) 页面,选择 Create New Namespace(创建新的命名空间)。这将显示 New Namespace(新命名空间)页面; 按照 System Administration Guide(《系统管理指南》)中“Configuring InterSystems IRIS(配置 InterSystems IRIS)”章节中 “Create/Modify a Namespace(创建/修改命名空间)”该页的说明 , 确保选中了 Enable namespace for interoperability productions(为命名空间启用互操作性Production) 复选框。 选择靠近页面顶部的 Save(保存) ,然后在生成的日志末尾选择 Close(关闭)。 导入演示产品 要导入包含数据转换的演示Production,请使用此程序: 在管理门户(Management Portal)中,选择 Interoperability(互操作性) > Manage(管理) > Deployment Changes(部署变更) > Deploy(部署),进入 Deploy Production Changes(部署Production变更) 页面。 如果出现提示,请选择在完成此步骤之前创建的命名空间。 点击 Open Deployment(打开部署)。 进入您从 GitHub 下载文件的目录,选择 DTLStudentDemo.xml,然后点击 OK(确定)。 点击 Deploy(部署)。 点击 OK(確定)。 创建数据转换 InterSystems IRIS 提供了一个数据转换向导(Data Transformation Wizard),以加速和简化创建新数据转换的过程。在本演示中,您将创建一个数据转换,该数据转换连接与班级学生成绩相关的两个记录映射。要创建数据转换: 从管理门户(Management Portal)主页,选择 Interoperability(互操作性) > List(列表) > Data Transformations(数据转换)。 点击 New(新建)。数据转换向导(Data Transformation Wizard)打开。 在 Package(包)下拉列表中选择 Demo(演示)。 在 Name(名称) 字段中,输入一个独特的名称,如 DTLDemoTransform。 点击 Source Class(源类) 字段旁边的放大镜。 点击 Message Classes(信息类) > Demo(演示) > Complex Map(复杂映射) > StudentWCD > Record(记录)。 点击 Target Class(目标类) 字段旁边的放大镜。 点击 Message Classes(信息类) > Demo(演示) > Complex Map(复杂映射) > StudentPFFixed > Record(记录)。 点击 OK(确定)。新的数据转换会在 DTL 编辑器(DTL Editor)中打开。 转换数据 现在您已经创建了数据转换,使用 DTL编辑器(DTL Editor): 将数据从源(source)复制到目标(target),根据需要重新排列数据的顺序。 在课程编号的开头添加学院专用代码。 将最终成绩四舍五入为整数。 使用期末成绩来确定学生是通过还是不通过,并在目标文件中指出这个结果。 忽略目标中不需要的源数据。 复制数据 DTL 编辑器(DTL Editor)最强大、最省时的功能之一是能够将值从源(source)拖放到目标(target)的相应属性。您只需点击并按住源属性上的圆圈,并将其拖动到目标信息的属性。 要将值从源(source)复制到目标(target): 点击并按住源(source)的 ClassID 属性的圆圈(在编辑器[Editor]的左侧)。 将光标拖动到目标(target)的 ClassID 属性,直到它被高亮显示,然后释放鼠标按钮。 源(source)的 ClassID 的值将被复制到目标(target)的 ClassID 属性。 按照此程序,将下列源属性连接到相应的目标属性: 学生 ID(StudentID) 成绩(Grade) 姓氏(LastName) 名字(FirstName) 中间名(MiddleName) 编辑器(Editor)现在应该是这样的: 请注意,仅仅通过连接属性对(property pairs),您便已经更改了存储数据的顺序。 修改属性(Property)的值 在某些情况下,您希望在将源属性(source property)复制到相应的目标属性(target property)之前更改其值。在这个演示中,目标系统接受一个 ClassID,这个 ClassID 以两个字符的标识符开头,表示源(Source)的学院。源的信息不包括这个标识符,因此数据转换必须在将 ClassID 的值复制到目标信息之前修改它。 点击,连接源的 ClassID 属性和目标的 ClassID 属性的线上的圆圈。 请注意,编辑器(Editor)右侧的 Action(操作) 标签现在显示了连接两个 ClassID 属性时创建的 Assign 操作的信息。Property(属性) 字段被设置为 target.ClassID,Value(值)字段被设置为 source.ClassID。 将 Action(操作) 标签的 Value(值) 字段变更为: "UC."_source.ClassID。UC 是学院的标识符,它使用下划线添加到 ClassID 的开头,下划线是 InterSystems ObjectScript 编程语言中的连接操作符。这超出了本演示的范围,但它让您了解如何在转换中包含 ObjectScript 代码。 使用函数 在设置属性值时,您可以使用内置函数。在本演示中,使用 Round() 函数将最终成绩四舍五入为整数。 选择源的成绩(Grade)属性和目标的成绩(Grade)属性之间的连接器。 点击 Action(操作) 标签的 Value(值) 字段旁边的放大镜。 从 Function (函数) 下拉列表中选择 Round ( )。 点击 OK(确定定)。 将 Action(操作) 标签的 Value(值) 字段设置为:..Round(source.Grade) 使用操作表 请注意,当您将源属性(source property)映射到目标属性(target property)时,DTL 编辑器(DTL Editor)将 Set(设置)操作添加到图表下方的表格中。 虽然 DTL 编辑器(DTL Editor) 的图形化部分使可视化和快速执行操作变得容易,但有时使用图表下方的表格来进一步定义转换会更好。例如,在本演示中, 在源属性和目标属性之间单击图形连接是选择 Set(设置)操作的最快方法。然而,在更复杂的转换中,可能很难选择连接器。在这种情况下,从图表下方的表格中选择 Set(设置)操作会更容易些。 定义有条件的操作集 在转换数据时,只有在某些条件为真时,才能使用条件语句执行操作。在本演示中,您定义了一个转换,如果期末成绩大于或等于 65 分,则表示学生通过了该课程。要添加 If 语句来完成此操作: 确保最后一项是高亮显示的表格。If 语句位于高亮显示的操作之后。 从 Add Action(添加操作) 下拉列表中选择 If。 请注意,图表下方的表格中添加了一个 If 块。 在表格中选择 If 语句后, 在 Action(操作) 标签上定义 Condition(条件)字段为: target.Grade>=65。只有当目标的成绩(Grade) 属性值大于或等于 65 时,才会执行放在 If 块内的操作。 从 Add Action(添加操作)下拉列表中选择 Set(设置)。 在 Action(操作) 标签上,定义 Property(属性) 字段为:target.Pass。 定义 Value(值) 字段为 1。这是一个布尔值(boolean value),表示该学生通过了这门课程。 选择表格中的 else(其他) 操作。 从 Add Action(添加操作)下拉列表中选择 Set(设置)。 在 Action(操作) 标签上,定义 Property(属性) 字段为:target.Pass。 在 Action(操作) 标签上,定义 Value(值) 字段为 0。这是一个布尔值(boolean value),表示该学生没有通过这门课程。 if 块现在应该是这样的: 忽略来自源信息(Source Message)的数据 在演示中,请注意 Email、Phone 和 Phone1 属性没有连接到目标信息。不需要进一步的操作来防止源信息中的这些数据被复制到目标信息。 编译数据转换 您可以选择随时保存工作,但必须始终记住编译数据转换。在您点击 Compile(编译)之前,产品无法识别更改。 进行初步测试 DTL 编辑器(DTL Editor)使您能够快速测试数据转换,而不必在整个生产过程中运行信息。您只需输入测试信息,DTL 编辑器(DTL Editor)就会显示输出信息的样子。在本演示的这一点上,您将记录映射数据的 XML 表示(XML representation)粘贴到测试转换(Test Transform)工具中。 稍后,您将通过在产品中运行文本文件来测试这个转换。 记住在测试数据转换之前要编译它。 点击编辑器右侧的 Tools(工具) 标签。 点击 Test(测试)。 将以下数据复制并粘贴到 Input Message(输入信息)文本框中: <test> <Record> <ClassID>CS241</ClassID> <StudentID>930698</StudentID> <Grade>77.8</Grade> <LastName>Sutherland</LastName> <FirstName>David</FirstName> <MiddleName>Timothy</MiddleName> <Email>david.sutherland@mail.com</Email> <Phone>978-343-3940</Phone> <Phone1>978-343-0951</Phone1> </Record> </test> 点击 Test(测试)。 Output Message(输出信息)文本框现在应该是这样的: <Record> <StudentID>930698</StudentID> <ClassID>UC.CS241</ClassID> <Grade>78</Grade> <Pass>true</Pass> <FirstName>David</FirstName> <MiddleName>Timothy</MiddleName> <LastName>Sutherland</LastName> </Record> 提示: 在处理 HL7 或其他 EDI 信息时,您可以从示例信息中复制和粘贴原始文本来测试转换。您不需要信息的 XML 表示(XML representation)。 向产品添加转换 现在您已经创建并编译了数据转换,必须将其添加到产品中,以便将流经产品的源信息转换为发送到下游应用程序的信息。在本演示中,您将向与业务流程 DTLDemoRouter 关联的业务规则添加转换。 从管理门户(Management Portal)主页,进入 Interoperability(互操作性) > List(列表) > Productions(产品)。 选择 Demo.ComplexMap.SemesterProduction 并点击 Open(打开)。 选择 Processes(进程)下的 DTLDemoRouter。 在 Settings(设置)标签上,点击 Business Rule Name(业务规则名称)字段旁边的放大镜。 双击位于业务规则 send(发送)操作中的 transform(转换)形状。 在 Data Transform Selector(数据转换选择器) 对话框中,选择您为这个演示创建的数据转换。 点击 OK(確定)。 在业务规则编辑器(Business Rule Editor)中,点击 Save(保存)。 有关业务规则的更多信息,请参见 Developing Business Rules(《开发业务规则》)。 测试数据转换 现在您已经将数据转换添加到产品中,运行产品以查看您的演示如何运行。在这一步骤中: 创建产品接收和发送示例文件的目录。 启动产品。 将示例输入文件复制到正确的目录中。 比较目标文件和源文件的内容。 创建所需的目录 演示产品被定义为在实例的主机 c:\practice\in 中查找包含源数据的文件,并将目标文件编写到 c:\practice\out 中。如果您不能在主机的 c:\ drive 上创建目录,或者它不是 Windows 系统,您必须识别或创建替代目录,然后在继续之前修改产品的业务服务和业务操作。业务服务的 File Path(文件路径)设置定义了产品查找输入文件的位置,而业务操作的 File Path(文件路径)设置定义了发送目标文件的位置。 创建目录的方式这取决于使用的实例类型 ,如下所示: 对于由 ICM 部署的实例,可以使用带有 -machine 和 -interactive 选项的 icm exec 命令,在运行实例的容器中打开 bash shell,例如: icm exec -command bash -machine MYIRIS-AM-TEST-0004 -interactive 然后您可以在容器文件系统上创建目录。 对于任何容器化的实例, 无论是授权版还是社区版(Community Edition), 使用命令 docker exec -it container_name bash 在容器中打开 bash shell (社区版[Community Edition]容器的名称是 try-iris)。然后在容器文件系统上创建目录。 对于 InterSystems 学习实验室(Learning Labs),使用集成 IDE 中的命令行终端,在共享(Shared)文件夹中创建新文件夹;您可以在 /home/project/shared 下的管理门户(Management Portal)中浏览到这些。 对于已安装的实例,在本地文件系统上创建目录。 本练习的其余部分假设目录路径为 c:\practice\in 和 c:\practice\out;如果不同,请替换为正确的路径。 启动产品 要启动包含演示数据转换的产品: 从管理门户(Management Portal)主页,进入 Interoperability(互操作性) > List(列表) > Productions(产品)。 选择 Demo.ComplexMap.SemesterProduction 并点击 Open(打开)。 点击 Start(开始)。 复制 .CSV 文件到目录 产品被定义为接受一个 .CSV 文件,其中包含来自 c:\practice\in 的学生信息。将 input.csv 文件从包含 GitHub 文件的目录复制到输入目录,或者 c:\practice\in ,或者您创建并指定的其他目录。 只要产品在运行,该文件就应该在几秒钟内从目录中消失,这表明产品已经开始成功地处理该文件。 验证输出数据 演示产品使用复制到产品的输入目录中的 .Csv 文件,并使用数据转换将数据转换为具有新内容的不同格式。这个传出文件被复制到产品的输出目录中,要么是 c:\practice\out ,要么是您创建并指定的另一个目录,文件名为时间戳。 打开 input.csv 和输出文件并比较两者。 其他重要功能 本演示提供了开发和测试数据转换的基础知识。其他重要的、常用的功能包括: for each 语句遍历一个集合,对集合的每个成员执行相同的操作序列。这个集合可以是一个数组,在 HL7 或其他 EDI 信息的情况下,也可以是一个重复段。更多信息,请参见 Adding a For Each Action(添加 For Each 操作)。 子转换,它允许您模块化数据转换。数据转换可以使用子转换操作在操作流的任何点上运行另一个转换。您可以创建可重用转换的库, 这些库可以从其他转换调用,从而避免重复转换逻辑。例如,您可以针对HL7 V2消息中的段创建段转换,只要这些段出现在 EDI 信息中就可以重复使用。 支持 X12 和 EDIFACT 标准。当使用数据转换向导创建新的转换时,您可以指定信息类型是 X12 还是 EDIFACT。这允许您选择使用正确的模式填充 DTL 编辑器(DTL Editor)的文档类型。这些模式段的可视化表示在 DTL 编辑器(DTL Editor)中展开和折叠。 了解有关数据转换的更多信息 有关数据转换的更多细节,请参见: Developing DTL Transformations(《开发 DTL 转换》) Advanced Data Transformations(高级数据转换) (在线课程) Business Process and Data Transformation Language Reference(《业务流程和数据转换语言参考》)
文章
Hao Ma · 九月 22, 2021

IRIS 2021 技术文档 First Look 8 - 技术概要:ODBC和InterSystems数据库

技术概要:ODBC 和 InterSystems 数据库 如果您希望在 InterSystems IRIS®数据平台上使用 ODBC,本文将介绍如何设置它。要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems 技术概要(InterSystems First Looks)。 1 ODBC: 如何在 InterSystems IRIS 中使用它InterSystems 提供了一个完全兼容的(ODBC 3.5)ODBC 驱动程序,您可以使用它通过 ODBC 访问 InterSystems IRIS 数据库。当您安装 InterSystems IRIS 时,默认安装该驱动程序。为了开始在 InterSystems IRIS 中使用 ODBC,您只需要在 InterSystems IRIS 实例上配置驱动程序。本技术概要(First Look)文档对这一过程进行了概述。如果您还不熟悉 ODBC,请参见本文档末尾的 "了解更多信息" 一节中的链接,以获得更多信息。 2 用前须知要使用这个程序,您需要一个安装了 InterSystems IRIS 实例的 Windows 系统。有关如何安装和授权 InterSystems IRIS 开发实例的说明,请参见InterSystems IRIS Basics: Installation(《InterSystems IRIS 基础:安装》)。 3 在 Windows 上设置 ODBC本节介绍如何在 Windows 上为 InterSystems IRIS 数据库创建 DSN。本节中的说明假定您已经安装了 InterSystems ODBC 驱动程序。默认情况下,标准的 InterSystems IRIS 安装过程会安装驱动程序,所以除非您执行了自定义安装,否则驱动程序应该存在于您的实例中。要使应用程序能够通过 ODBC 访问 InterSystems IRIS 数据库,您需要创建一个 DSN,该 DSN 为 ODBC 客户端驱动程序定义数据库的位置。在 Windows 上,您可以从 Windows 控制面板执行此操作,如下所示:1. 打开Windows Administrative Tools control panel(Windows 管理工具控制面板)。2. 选择 Data Sources(数据源)(ODBC)。3. 在 User DSN(用户 DSN) 标签上,选择 Add(添加)。4. 选择 InterSystems ODBC 并点击 Finish(完成)。 技术概要:ODBC 和 InterSystems 数据库 1 了解更多有关 ODBC 的信息 DSN 创建完成后,将显示 InterSystems ODBC Data Source Setup (InterSystems ODBC 数据源设置)对话框。图 1:InterSystems ODBC 数据源设置对话框 5. 输入必要的配置细节:• 输入 DSN 的名称和描述。• 输入与此 DSN 代表的 InterSystems IRIS 数据库相对应的 IP 地址、端口号和命名空间。• 选择一种身份验证方法,并输入或选择适合 InterSystems IRIS 实例的其他安全信息。 6. 选择 Test Connection(测试连接) 按钮来测试您的设置是否正确。 如果连接测试成功,那么恭喜您!您已经完成了 InterSystems IRIS 数据库的设置,以使用 ODBC。现在您可以修改支持 ODBC 的应用程序,以使用刚刚创建的 DSN。 4 了解更多有关 ODBC 的信息如果您更喜欢使用文件 DSN,请参见Using the InterSystems ODBC Driver guide(《使用 InterSystems ODBC 驱动程序指南》)中的 " Using File DSNs and DSN-less Connections(使用文件 DSN 和无 DSN 连接) "一章,以了解相关说明。InterSystems IRIS 还支持 UNIX®上的 ODBC;详情请参见Using the InterSystems ODBC Driver guide(《使用 InterSystems ODBC 驱动程序指南》)中的 " Using an InterSystems Database as an ODBC Data Source on UNIX®(在 UNIX®上使用 InterSystems 数据库作为 ODBC 数据源)"一章。若要在 Windows 上使用 TLS 保护 ODBC 连接,请参见Connecting from a Windows Client Using a Settings File(《使用设置文件从 Windows 客户端进行连接》)。 要了解更多有关 ODBC 和 InterSystems IRIS 的信息,请参见:• Using the InterSystems ODBC Driver(《使用 InterSystems ODBC 驱动程序》) — InterSystems 文档:使用 ODBC 的逐步说明• Using InterSystems SQL(《使用 InterSystems SQL》) — InterSystems 文档:使用 SQL 的逐步说明• InterSystems SQL Reference(《InterSystems SQL 参考文献》) — InterSystems 文档:SQL 参考文献 2 技术概要: ODBC 和 InterSystems 数据库 了解更多有关 ODBC 的信息 • SQL Optimization Guide(《SQL 优化指南》) — InterSystems 文档:优化 InterSystems SQL 性能的指南
文章
Hao Ma · 九月 22, 2021

IRIS 2021 技术文档 First Look 3 - 连接一个IDE

InterSystems IRIS 基础:连接一个 IDE 本文档告诉您如何快速连接您的集成开发环境(IDE),用于 ObjectScript、Java、.NET、Python 或 JavaScript/Node.js 的集成开发环境连接到 InterSystems IRIS® 的一个实例,并使用从 GitHub 下载的模板文件验证您是否已经成功连接。此外,接下来的两节还包括以下内容:• 部署 InterSystems IRIS列出用于部署 InterSystems IRIS 的已授权和免费评估实例的选项。如果您还没有一个可以使用的实例,请查看本节。• InterSystems IRIS 连接信息详细介绍了将 IDE 连接到已授权或免费的 InterSystems IRIS 实例,以及以其他方式与之进行交互所需的信息 ,并解释了如何获得实例的信息。无论您想用哪个 IDE 连接到 InterSystems IRIS,都要查看涉及您所使用的实例类型的部分。 1 部署 InterSystems IRIS本节涵盖了已授权的实例和免费的评估实例。 1.1 部署已授权的实例如果您已经从 InterSystems 购买了一个或多个许可证,您可以使用以下方法之一来部署一个已授权的 InterSystems IRIS 实例:• InterSystems 云管理器• InterSystems Kubernetes Operator• InterSystems IRIS 容器镜像• InterSystems IRIS 安装套件 当从容器镜像或安装套件进行部署时,您可以使用配置合并功能 来支持自动部署。 1.1.1 InterSystems 云管理器InterSystems 云管理器(ICM)是 InterSystems IRIS 的端到端配置和部署解决方案。使用 ICM,您可以在公共云平台(如谷歌云平台、亚马逊网络服务和微软 Azure)或您的私有 VMware vSphere 云中配置基础设施和部署容器化服务,您也可以在现有的虚拟或硬件系统中部署服务。您可以将您的自定义和第三方容器与 InterSystems 的容器一起部署,而且 ICM 还可以从 InterSystems IRIS 安装套件中安装。 部署 InterSystems IRIS 关于 ICM 的详细文档,请参见 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)。您可以通个First Look: InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》)试用 ICM。关于如何获得和部署 ICM 镜像的信息, 请参见InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)中的Launch ICM(启动 ICM)。 1.1.2 InterSystems Kubernetes OperatorKubernetes 是一个开源的编配引擎,用于自动化部署、扩展和管理容器化工作负载和服务。您可定义您想要部署的容器化服务和想要使用的治理策略;Kubernetes 以最有效的方式透明地提供所需的资源,在部署偏离规格时修复或恢复,并自动或按需扩展。InterSystems Kubernetes Operator(IKO)通过 IrisCluster 自定义资源扩展了 Kubernetes API,该资源可以在任何 Kubernetes 平台上作为 InterSystems IRIS 分片集群、分布式缓存集群或独立实例(所有可选镜像)进行部署。IKO 还为 Kubernetes 增加了 InterSystems IRIS 特定的集群管理功能,实现了任务的自动化 ,如向集群添加节点,否则您必须通过与实例直接交互来手动完成。关于使用 IKO 的信息,请参见Using the InterSystems Kubernetes Operator(《使用 InterSystems Kubernetes Operator》)。 1.1.3 InterSystems IRIS 容器镜像InterSystems 的 Docker 镜像让您可以使用自己的工具和方法将 InterSystems IRIS 部署到 Linux 主机——云、虚拟或物理主机上的容器中。对特定实例数据的持久性存储使容器化的 InterSystems IRIS 易于升级,因此您可以随时将现有的配置转移到最新版本的 InterSystems IRIS 中,而几乎不存在任何问题,停机时间也很少。关于使用 InterSystems IRIS 镜像的详细指南,请参见Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)。如果想亲身体验一下 InterSystems IRIS 镜像和容器,请尝试First Look: InterSystems Products in Containers(《技术概要:容器中的 InterSystems 产品》)。关于如何获得 InterSystems IRIS 镜像的信息,请参见Running InterSystems Products in Containers(《在容器中运行 InterSystems产品》)中的Downloading the InterSystems IRIS Image(《下载 InterSystems IRIS 镜像》)。您可以使用安装在谷歌云平台、微软 Azure 或亚马逊网络服务公共云平台上的 InterSystems IRIS 容器镜像和 Docker 来配置 BYOL(自带许可证)云节点, 然后添加您的许可并按照Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)或First Look: InterSystems Products in Containers(《技术概要:容器中的 InterSystems 产品》)中的描述,从该镜像中运行 InterSystems IRIS 容器。欲了解更多信息,请参见Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的Deploy InterSystems IRIS BYOL on a Cloud Node(《在云节点上部署 InterSystems IRIS BYOL》)。(您也可以使用免费的 InterSystems IRIS 社区版镜像来使用这些文档。) 1.1.4 InterSystems IRIS 安装套件您可以通过从 InterSystems 全球响应中心 (WRC)下载区获得您的平台的最新安装套件,在您的本地机器或网络上的另一台机器上安装和许可 InterSystems IRIS 的开发实例。有关基本的安装说明,请参见 InterSystems IRIS Basics: Installation (《InterSystems IRIS 基础:安装》);详细信息请参见安装指南。 1.1.5 使用配置合并进行部署配置合并功能在 Linux 和 UNIX®系统上可用,让您可以改变从同一镜像部署的 InterSystems IRIS 容器的配置,或从同一套件安装的本地实例,只需简单地将所需的声明性配置合并文件应用于部署的每个实例。这个合并文件, 也可以在重启现有实例或使用 iris 合并命令时应用,更新实例的配置参数文件 (CPF), 其中包含了大部分的配置设置;这些设置在每次启动时都会从 CPF 读取,包括实例部署后的第一次启动。当您在部署过程中应用配置合并时,实际上是用您自己的更新版本替换了随实例提供的默认 CPF。InterSystems 云管理器 和 InterSystems Kubernetes Operator 都包含了配置合并功能。 InterSystems IRIS 连接信息 有关使用配置合并的信息,请参见Configuration Parameter File Reference.(配置参数文件参考)中的Using Configuration Merge to Deploy and Reconfigure InterSystems IRIS(使用配置合并来部署和重新配置 InterSystems IRIS)和Create and Use a Configuration Merge File(创建和使用配置合并文件)。 1.2 部署免费的评估实例如果您还不是 InterSystems IRIS 的用户,您可以通过部署一个免费的评估实例,来探索它的许多功能,并使用您喜欢的语言和工具以及您自己的代码来试用它。有以下几个选项可以做到这一点:• 在云或者您自己的系统上部署 InterSystems IRIS 社区版实例。• 在网上启动一个 InterSystems 学习实验室(Learning Labs)实例。 1.2.1 InterSystems IRIS 社区版InterSystems IRIS 社区版有一个免费的内置 13 个月的许可证(和一些功能限制)。您可以通过两种方式部署社区版:• 在谷歌云平台、微软 Azure 或亚马逊网络服务公共云平台上提供一个托管运行社区版容器的云节点。• 从 InterSystems Container Registry (ICR)或 Docker Store 中提取社区版镜像,并使用它在您选择的系统上部署容器。 有关在云或自己的系统上部署和使用 InterSystems IRIS 社区版的说明,请参见Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)。 1.2.2 InterSystems 学习实验室(Learning Labs)InterSystems 学习实验室(Learning Labs)网页可以让您快速、轻松地启动 InterSystems IRIS 实验室实例,用于培训、开发和测试,并有 30 天的免费许可。您的 InterSystems 学习实验室实例包括一个集成的 IDE 和大量的示例,您可以连接您自己的 IDE。要启动 InterSystems 学习实验室实例,您必须登录 learning.intersystems.com;如果您没有账户,可以轻松创建一个。(与社区版一样,学习实验室实例有一些功能限制。) 2 InterSystems IRIS 连接信息(Connection Information)要将一个 IDE 连接到一个 InterSystems IRIS 实例,首先需要选择实例,然后确定所需的连接信息,如下所示:• 主机标识符:实例主机的 IP 地址或主机名。• 实例的超级服务器和 web 服务器端口号。• 实例的有效凭证。• 实例上现有命名空间的名称。 了解实例基于 Web 管理门户的 URL,以及如何在实例上打开 InterSystems 终端 (这需要实例的名称),这也是很有帮助的。如何确定这些信息取决于您如何部署您正在使用的实例,如下所示:• InterSystems 云管理器(Cloud Manager) InterSystems IRIS 连接信息 • 在一个容器中部署 InterSystems IRIS• 从套件中安装 InterSystems IRIS• InterSystems IRIS 社区版• InterSystems 学习实验室(Learning Labs) 2.1 InterSystems 云管理器(Cloud Manager)对于由 ICM 部署的容器中的 InterSystems IRIS 实例,主机标识符是容器所部署的配置或现有节点的 IP 地址或主机名。您可以随时使用 icm inventory 命令查看您部署的节点的主机名和 IP 地址。默认的超级服务器和 Web 服务器端口号分别为 1972 和 52773;您可以通过在 defaults.json 文件中加入 SuperServerPort 和 WebServerPort 属性来指定不同的端口号。管理门户的 URL 门户包含了主机标识符和 web 服务器端口,例如 http://40.122.36.160:52773/csp/sys/UtilHome.csp。IDE 连接或管理门户的凭证是您在基础设施上用 icm run 命令部署服务时设置的预定义用户账户之一和默认密码,或者是您先前添加到实例的账户和密码。要打开 ICM 部署的实例的终端,可以使用带有-interactive 选项和 -machine 选项的 icm session 命令 ,指定托管实例的节点;不需要验证。您始终可以将您的 IDE 连接到所有 InterSystems IRIS 实例中存在的 USERnamespace,但是如果您在部署时使用了 definitions.json 文件中的 Namespace 属性或 -namespace 选项以指定不同的默认执行命名空间, 您可能希望连接到该namespace。您还可以连接到以前使用管理门户创建的其他名称空间。 2.2 在一个容器中部署 InterSystems IRIS对于您从 InterSystems 镜像(包括在 BYOL 云节点上)部署的容器中的 InterSystems IRIS 实例,主机标识符是容器所运行的系统的 IP 地址或主机名。超级服务器和 Web 服务器的端口号取决于您在用 docker run 命令创建和启动容器时如何发布实例的端口;更多信息,请参见Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的Running InterSystems IRIS Containers(运行 InterSystems IRIS 容器)。举个例子,如果您把实例的 Web 服务器端口(始终是 52773)发布为 52773(如引用部分所述),并且您的浏览器与容器在同一个系统上运行,那么管理门户的 URL 是 http:/localhost:52773/csp/sys/UtilHome.csp。IDE 连接或管理门户的凭证是您在创建容器时设置的预定义用户账户之一和默认密码 [请参见Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的Authentication and Passwords(验证和密码)],或者是您先前添加到实例中的账户和密码。要为容器中的实例打开Terminal,您可以使用 docker exec 命令在容器中运行 iris terminal命令,您也可以使用 docker exec 在容器中打开一个 shell,并从那里运行 iris ternimal ;有关示例,请参见Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的Interacting Using the InterSystems Terminal(使用 InterSystems Terminal进行交互)。要使用 iris terminal,您需要实例名称,在 InterSystems 的任何容器中,该名称始终为 IRIS。如Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的Ownership and Directories(所有权和目录)所述,使用 docker exec 从 InterSystems IRIS 容器外发出的命令在容器内以 irisowner 身份执行,不需要身份验证,因此您无需登录Terminal。您始终可以将您的 IDE 连接到存在于所有 InterSystems IRIS 实例中的 USER namespace,但您也可以连接到您先前使用管理门户创建的不同的namespace。 InterSystems IRIS 连接信息 2.3 从套件中安装 InterSystems IRIS对于从套件中安装的 InterSystems IRIS 实例,主机标识符是该实例运行的系统的主机名或 IP 地址;如果是本地安装,可以使用 localhost 。InterSystems IRIS 的安装将超级服务器和 web 服务器的端口号默认设置为 1972 和 52773。但是,如果您在系统中安装了一个以上的 InterSystems IRIS 实例,那么这些实例的超级服务器和 web 服务器的端口是不同的;要显示所有实例的端口号,您可以在操作系统的命令行中使用 iris list 命令。在 Windows 系统中,您可以通过点击系统托盘中的 InterSystems IRIS 图标并选择 Management Portal 来打开管理门户。在所有系统上,您都可以使用 URL http://host:webserverport/csp/sys/UtilHome.csp, 其中 host 是主机标识符, port 是 web 服务器端口号, 例如 http://localhost:52773/csp/sys/UtilHome.csp。要打开已安装实例的终端: • 在 Windows 系统上, 您可以选择 InterSystems IRIS 启动菜单上的 Terminal 选项。• 在所有的系统上,您可以在操作系统的命令行上使用 iris terminal命令,把实例名称作为参数。实例名称是在您安装实例时设置的,不能更改;您可以使用 iris list 命令来显示它。 用于所有目的的凭证是预定义用户账户(predefined user accounts)之一和默认密码 SYS(这样做后会提示您立即更改账户的密码),或者是您先前添加到实例的账户和密码。您始终可以将您的 IDE 连接到存在于所有 InterSystems IRIS 实例中的 USER namespace,但您也可以连接到您先前使用管理门户创建的不同的namespace。 2.4 InterSystems IRIS 社区版您可以通过以下两种方式之一部署社区版:• 当您在公共云平台上配置托管运行的 InterSystems IRIS 社区版容器的云节点时, 云节点的 IP 地址(主机标识符)、实例的超级服务器和 Web 服务器端口号(始终分别为 1972 和 52773),以及实例的管理门户 URL 在您首次使用 SSH 连接到节点时显示,并且可以通过在 Linux 命令行上输入 iris info 随时显示。门户网站的 URL 包含了 IP 地址和 web 服务器端口,例如 http://40.122.36.160:52773/csp/sys/UtilHome.csp。• 当您从 InterSystems Container Registry 或 Docker Store 提取社区版镜像并在您选择的系统上部署 InterSystems IRIS 社区版容器时,主机标识符是容器运行所在系统的 IP 地址或主机名。超级服务器和 Web 服务器的端口号取决于您在用 docker run 命令创建和启动容器时如何发布实例的端口,如在Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的Deploying InterSystems IRIS Community Edition on Your Own System(在您自己的系统上部署 InterSystems IRIS 社区版)中所述。举个例子,如果您把实例的 web 服务器端口(始终是 52773)发布为 52773(如引用部分所述),并且您的浏览器与容器在同一个系统上运行,那么管理门户的 URL 是 http:/localhost:52773/csp/sys/UtilHome.csp。 有关为任何社区版实例打开终端的信息,请参见Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的Interacting Using InterSystems Terminal(使用 InterSystems 终端进行交互)。IDE 连接和管理门户的凭证是预定义用户账户之一,以及您在第一次连接云节点修改密码时提供的新的默认密码[请参见Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的Change the Default Passwords(修改默认密码)],或者默认密码 SYS,如果您在自己的系统上或者在没有先连接到节点的情况下登录到云实例。当您使用 SYS 时,系统会提示您 ObjectScript IDE 立即修改您所使用的账户的密码。您也可以使用您以前在实例上创建的账户。您始终可以将您的 IDE 连接到存在于所有 InterSystems IRIS 实例中的USER namespace,但您也可以连接到您以前使用管理门户创建的不同namespace。 2.5 InterSystems 学习实验室(Learning Labs)到容器化 InterSystems IRIS 实例的所有连接都是您的 InterSystems 学习实验室(learning labs)配置的一部分,在学习实验室启动期间,您需要的所有连接信息都显示在启动页面上,如下所示:• 集成 IDE 的 URL。• 一套用于所有目的的凭证。• 管理门户 URL。• Web 服务器端口号(始终是 80)。• 在外部连接下,服务器的 IP 地址和超级服务器的端口号(标记为 InterSystems IP 和 InterSystems 端口);您可以用它们将 IDE(如 InterSystems Studio 或 Visual Studio Code)与 ObjectScript 扩展连接到实例。 在集成 IDE 的 InterSystems 菜单上有一个Terminal选项(Management Portal 选项也是如此),所以您不需要跟踪实例名称。 3 ObjectScript IDE本节介绍了您可以用来在 InterSystems IRIS 实例上开发 ObjectScript 代码的 IDE:带有 ObjectScript 扩展的 Visual Studio Code (VS Code),以及 Studio。 3.1 Visual Studio CodeVisual Studio Code(VS Code)是微软为 Windows、Linux 和 macOS 制作的一个免费源代码编辑器。虽然它可以作为带有 InterSystems IRIS 的.NET、Python 或 JavaScript IDE 开箱即用,但可用的扩展功能使您能够使用 VS Code 开发 ObjectScript 代码,这些代码在客户端系统上存储和版本化,在 InterSystems IRIS 服务器上编译、运行和调试。关于安装扩展,连接到一个或多个 InterSystems IRIS 实例,以及使用 VS Code for ObjectScript 的信息,请访问 https://intersystems-community.github.io/vscode- objectscript/。 VS Code 可以连接到任何 InterSystems IRIS 实例,无论该实例在哪个平台上运行,使用主机的 DNS 名称或 IP 地址、实例的名称和实例的超级服务器端口号,默认为 1972(但如果系统上安装了多个实例,则可能不同)。 3.2 StudioInterSystems IRIS 应用程序开发人员还可以使用 Studio IDE,这是一个在 Windows 系统上运行的客户端应用程序;详细信息请参见使用 Studio 。Studio 可以连接到任何 InterSystems IRIS 实例,无论该实例在哪个平台上运行,使用主机的 DNS 名称或 IP 地址、实例的名称和实例的超级服务器端口号,默认为 1972(但如果系统上安装了多个实例,则可能有所不同)。 Java IDE 4 Java IDE本节提供了 Visual Studio Code (带有 Java 编码包或 Java 扩展包)、Eclipse、IntelliJ 和 NetBeans 的连接说明,您可以用它们来开发 Java 代码,使用 InterSystems Native API、JDBC 和 Java 网关与 InterSystems IRIS 交互。 4.1 Visual Studio Code要将 Visual Studio Code 连接到 InterSystems IRIS,请使用以下步骤。(如有必要,请登录 GitHub。)1. 在您的 web 浏览器中,下载或克隆 https://github.com/intersystems/Samples-java-helloworld。2. 在 Visual Studio Code 中,使用 File > Open Folder 来打开您最近从 GitHub 下载或克隆的文件夹。3. 选择并打开 src/main/java.com.intersystems.samples.helloworld.java。4. 在主要方法的顶部的变量声明中,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。这些值用于构造 InterSystems JDBC 连接字符串,格式为 jdbc:IRIS://ipAddress:superserverPort/namespace, 例如 jdbc:IRIS://12.345.678.910:51773/USER。5. 使用 View > Terminal 来打开终端并执行以下命令: javac -cp ".:intersystems-jdbc-3.2.0.jar" HelloWorld.java java -cp ".:intersystems-jdbc-3.2.0.jar" HelloWorld 6. 输出窗格显示信息 Hello World! You have successfully connected to InterSystems IRIS via JDBC. 4.2 Eclipse要将 Eclipse 连接到 InterSystems IRIS,请使用以下步骤。(点击 Next,根据需要推进到每个对话框的下一个面板。)首先,导入示例包,1. 选择 File > Import > Git > Projects from Git。2. 选择 Clone URI。将 https://github.com/intersystems/Samples-java-helloworld 复制并粘贴到 URI 字段中。3. 选择 master 分支,配置本地存储,然后选择 Import existing Eclipse projects。4. 点击 Finish 确认导入。 接下来,更新示例代码并运行它。1. 打开 samples-java-helloworld > src > main.java.com.intersystems.samples > HelloWorld.java 并做如下修改:a. 将顶层包声明更改为 package main.java.com.intersystems.samples;.b. 在主要方法的顶部变量声明中,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。这些值用于构造 InterSystems JDBC 连接字符串,格式为 jdbc:IRIS://ipAddress:superserverPort/namespace, 例如 jdbc:IRIS://12.345.678.910:1972/USER。 2. 通过选择 Run > Run 来运行代码。 Java IDE 3. Console 标签显示的信息是 Hello World! You have successfully connected to InterSystems IRIS via JDBC. 如果您没有成功,请通过以下操作确认 Java 执行环境设置正确:1. 右键点击 Package Explorer 窗格中的 samples-java-helloworld 项目,然后选择 Build Path > Configure Build Path...。2. 在 Libraries 标签上,选择 Add Library > JRE System Library > Execution environment >并选择一个执行环境,如 JRE-1.1 (jre 1.8.0_172)。点击 Finish,然后点击 Apply and Close。 4.3 IntelliJ要将 IntelliJ 连接到 InterSystems IRIS,请使用以下步骤。(点击 Next,根据需要推进到每个对话框的下一个面板。)首先,创建示例项目。1. 选择 VCS > Checkout from Version Control > Git。2. 在克隆存储库对话框中,a. 将 https://github.com/intersystems/Samples-java-helloworld 复制并粘贴到 Clone URI 字段中。b. 对于 Directory 字段,输入要创建本地 GitHub 存储库的位置的路径。 3. 点击 Clone,然后在弹出的窗口中选择 Yes ,以创建一个基于此源的项目。 接下来,更新示例代码并运行它。1. 在主要方法的顶部的变量声明中,打开 src/main/java.com.intersystems.samples.helloworld.java 并为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。这些值用于构造 InterSystems JDBC 连接字符串,格式为 jdbc:IRIS://ipAddress:superserverPort/namespace, 例如 jdbc:IRIS://12.345.678.910:1972/USER。2. 在 Project 窗格中,右键单击 HelloWorld.java 并选择 Run ‘HelloWorld.main()’。3. Output 窗格显示的信息是 Hello World! You have successfully connected to InterSystems IRIS via JDBC. 如果您没有成功,请通过以下操作确认 Java 执行环境设置正确:1. 选择 Build Path > Build Project。2. 编辑配置并添加一个新的应用程序配置,选择 com.intersystems.samples.HelloWorld 作为主类。3. 如果错误 Error:java: invalid source release: 9 显现,在以下位置将项目 SDK 和项目语言级别修改为 1.8 :• File > Project Structure > Project Settings• File > Project Structure > Module Settings > Sources: Language Level 标签• File > Project Structure > Module Settings > Dependencies: Module SDK 标签 .NET IDE 4.4 NetBeans要将 NetBeans 连接到 InterSystems IRIS,请使用以下步骤。(点击 Next,根据需要推进到每个对话框的下一个面板。)首先,创建示例项目。1. 选择 Team > Git > Clone。2. 将 https://github.com/intersystems/Samples-java-helloworld 复制粘贴到 Repository URL 字段中。3. 选择 Master 作为要提取的分支,选择创建本地 GitHub 存储库的位置,然后点击 Finish。 接下来,更新示例代码并运行它。1. 在主要方法的顶部的变量声明中,打开 HelloWorld.java 并为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。这些值用于构造 InterSystems JDBC 连接字符串,格式为 jdbc:IRIS://ipAddress:superserverPort/namespace, 例如 jdbc:IRIS://12.345.678.910:1972/USER。2. 在 Project 窗格中,打开 Dependencies 文件夹,然后右键点击 intersystems-jdbc-3.0.0.jar 并选择 Manually install artifact。导航到您最近克隆的文件夹,选择 intersystems-jdbc-3.0.0.jar,然后点击 Install Locally。3. 在 Project 窗格中,右键单击 HelloWorld.java 并选择 Run File。4. Output 窗格显示的信息是 Hello World! You have successfully connected to InterSystems IRIS via JDBC. 5 .NET IDE本节为微软的 Visual Studio 和 Visual Studio Code 提供连接说明,您可以用它来开发.NET 代码,这些代码通过 InterSystems Native API、ADO.NET Managed Provider for .NET、InterSystems XEP 和.NET 网关与 InterSystems IRIS 交互。 5.1 Visual Studio要将 Visual Studio 连接到 InterSystems IRIS,请使用以下步骤。(如有必要,请登录 GitHub。) 首先,创建示例解决方案。1. 选择 View > Team Explorer。2. 在 Team Explorer – Connect 窗格中, 选择 Local Git Repositories > Clone, 将 https://github.com/inter- systems/Samples-dotnet-helloworld 复制粘贴到 URL 框中, 并点击 Clone。 接下来,更新示例代码并运行它。1. 双击 HelloWorld.sln 来查看解决方案中的文件,然后打开 helloworld.cs。2. 使用变量声明,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》),3. 按 F5 键,运行该程序。 Python IDE 4. 命令窗口显示的信息是 Hello World! You have successfully connected to InterSystems IRIS. Press any key to continue. 5.2 Visual Studio Code通过 ObjectScript 扩展,Visual Studio Code 可以用来在 InterSystems IRIS 上开发 ObjectScript 代码;请参见ObjectScript IDE。要将 Visual Studio Code 连接到 InterSystems IRIS,请使用以下步骤。(如有必要,请登录 GitHub。)1. 在您的 web 浏览器中,下载或克隆 https://github.com/intersystems/Samples-dotnet-helloworld。2. 在 Visual Studio Code 中,使用 File > Open Folder 来打开您最近从 GitHub 下载或克隆的文件夹。3. 拓展 samples-dotnet-helloworld 并选择 helloworld.cs。4. 使用变量声明,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。5. 使用 View > Terminal 来打开终端并执行以下命令: csc /reference:InterSystems.Data.IRISClient.dll helloworld.cs.\helloworld.exe 6. 输出窗格显示的信息是 Hello World! You have successfully connected to InterSystems IRIS.Press any key to continue. 6 Python IDE本节提供了将您最喜欢的以 Python 为中心的 IDE(如 Visual Studio Code、PyCharm、Spyder、IDLE/IdleX 或 Vim)连接到 InterSystems IRIS 的说明。当您使用以下步骤连接后(如有必要,请登录 GitHub),您可以使用技术概要:InterSystems IRIS Native API for Python 来探索 InterSystems IRIS Native API for Python。1. 在您的 web 浏览器中,下载或克隆 https://github.com/intersystems/Samples-python-helloworld。2. 在您的 IDE 中,打开您最近从 GitHub 下载或克隆的文件夹,然后打开 hello_world.py。3. 使用变量声明,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。4. 在您的 IDE 的终端,做如下操作:a. 使用以下命令之一安装 InterSystems Native API for Python:• 微软 Windows:pip install wheel\irisnative-1.0.0-cp34.cp35.cp36.cp37-none-win_amd64.whl • UNIX®/Linux:pip install wheel/irisnative-1.0.0-cp34-abi3-linux_x86_64.whl • Apple macOS:pip install wheel/irisnative-1.0.0-cp34-abi3-macosx_10_13_x86_64.macosx_10_14_x86_64.whl b. 使用命令 python hello_world.py 运行代码。 Javascript IDE 5. 输出窗格显示信息 Hello World! You have successfully connected to InterSystems IRIS. 注意: Python 代码示例和支持轮文件是为 Python 3 设计的,因为 Python 2 将在 2020 年退休;Python 2 版本可从 InterSystems Learning Services 获得。 7 Javascript IDE本节提供了将您最喜欢的 JavaScript 和 Node.js 的 IDE(如 Visual Studio Code、Vim 或 Webstorm)连接到 InterSystems IRIS 的说明。当您使用以下步骤连接后(如有必要,请登录 GitHub),您可以使用技术概要:InterSystems IRIS Native API for Node.js 来探索 InterSystems IRIS Native API for Node.js。1. 在您的 web 浏览器中,下载或克隆 https://github.com/intersystems/Samples-nodejs-helloworld。2. 在您的 IDE 中,打开您最近从 GitHub 下载或克隆的文件夹,然后打开 hello_world.js。3. 使用变量声明,为您的实例配置用户名、密码、IP 地址和端口(请参见 InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)。4. 在您的 IDE 的终端,做如下操作:a. 使用命令 npm install ––save intersystems-iris-native 安装 InterSystems Native API for Node.js。b. 使用命令 node hello_world.js 运行代码。 5. 输出窗格显示信息 Hello World! You have successfully connected to InterSystems IRIS.
文章
Jingwei Wang · 九月 22, 2021

IRIS 2021 技术文档 First Look 6 使用具有互操作性的Production连接系统

为什么要连接系统? 连接系统可以让一个系统处理来自非本系统的信息。例如,以下场景需要连接系统: 为了提高效率,最初设计为执行单一功能的系统需要集成。例如,您可以通过集成跟踪库存、订购材料、记录销售和控制运输的各个系统来提高效率。 系统合并后,在不同机构中执行相同功能的系统需要协同工作才能使统一的机构有效。 将系统连接在一起时,您可能会面临一些挑战,例如: 不同系统使用不同的通信协议:一个系统可能使用TCP,另一个系统使用SOAP,第三个系统使用REST。 不同系统使用不同格式或基于不同标准的不同消息。 需要保证消息成功传递到正确的系统,并能够检测和纠正故障。 必须监控传输消息的系统,如果一次消息过多,则为消息提供一个队列,并监控整体系统性能以确保没有任何障碍。 虽然可以编写自定义应用程序来连接系统,但开发一款InterSystems IRIS® 产品要容易得多,也快得多。 InterSystems IRIS 提供了一个框架,允许连接系统,并最大限度地减少或消除对自定义代码的需求。 Production介绍 InterSystems IRIS Production是一个集成框架,用于轻松连接系统和开发互操作性应用程序。产品Production提供包含各种消息格式和通信协议的内置连接。您可以轻松添加其他格式和协议,并通过编写代码或使用图形向导定义业务逻辑和消息转换。产品提供消息的持久存储,允许跟踪消息的路径并审核消息是否成功传递。一个Production由业务服务(BS)、业务流程(BP)和业务操作(BO)组成: 业务服务(BS)与外部系统连接并接收Production来自外部系统的消息。 业务流程(BP)允许您定义业务逻辑,包括路由和消息转换。 业务操作(BO)与外部系统连接并将消息发送给它们。 将系统连接在一起时,让所有系统互相理解它们的消息和文档是有挑战性的。例如,思考以下问题: 您有两个独立的系统:一个是从多个联网设备采集数据,另一个是跟踪损坏的设备和维修进程的工单系统。 当前程序依赖于人工干预来监控设备并启动维修进程。这导致了拖延情况且不可靠。 您的任务是将两个系统连接在一起:监控正在收集的数据并自动启动修复进程。您知道如何检测数据收集系统中的故障设备并知道如何启动维修,尽管两个系统所存储的数据代表同一项目,但是两个系统的存储数据格式并不兼容。 您还需要记录数据收集系统启动维修时的操作。 可以使用InterSystems IRIS 产品解决这个问题。它提供了一个定义接口的框架,该接口接收来自数据采集系统的消息,将消息转换为维修系统可以理解的消息,然后将消息发送到维修系统。它还存储消息路径。 下面以一个简单的Production作为示例 出于演示目的,本文档中的Production使用文件适配器(file adapter)并将外部系统表示为文件。由于处理外部系统的大部分工作是由InterSystems IRIS 提供的适配器完成的,因此开发一款可以连接到含有 REST、TCP、SOAP 或HTTP 的外部系统的Production的过程与使用文件适配器开发产品非常相似。 使用文件适配器(File Adaptor)创建Production 在本节中,您将使用入站文件适配器和出站文件适配器创建Production。可以使用 InterSystems IRIS 中内置的业务服务(BS)、业务流程(BP)和业务操作(BO),因此您无需下载任何代码。 尝试一下!使用文件适配器创建产品 想要尝试一下InterSystems IRIS 互操作性功能的在线视频演示吗?查看互操作行快速入门! 用前须知 要使用该程序,您需要一个正在运行的InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。如果您还没有一个可以使用的实例,如何部署每种类型实例的有关信息,请参阅InterSystems IRIS Basics: Connecting an IDE中的部署 InterSystems IRIS。 关于如何用Visual Studio 连接到您的InterSystems IRIS 实例,请参考InterSystems IRIS 连接信息和.Net IDEs。 创建支持互操作的命名空间(Namespace) 为了创建一个production,必须有支持互操作的命名空间。如果您已经创建了启用互操作的命名空间, 则可以将其用于该production。要创建新的支持互操作的命名空间,请遵照以下流程(首次安装InterSystems IRIS 时 创建的命名空间不支持互操作): 在浏览器中为实例打开Management Portal (管理门户)。 选择系统管理 > 配置 > 系统配置 > 命名空间,进入命名空间页面。 在命名空间页面,选择新建命名空间 ;根据系统配置指南中“配置InterSystems IRIS”一章中,对于“Create/Modify a Namespace(创建/修改命名空间)”说明,确保选中 Enable namespace for interoperability productions(为互操作性产品启用命名空间)复选框。 点击靠近页面顶部的保存按键,然后在结果日志的结尾选择关闭。 创建含有业务服务 (BS)和业务操作(BO)的简单production 在这一步中,您将: 创建一个新的production。 在该production中添加一项业务服务(BS)和两项业务操作(BO)。 配置业务服务(BS)和业务操作(BO)。 现在,您应该创建在托管InterSystems IRIS实例的系统上运行此production所需的四个目录。具体处理方法取决于所用的实例类型,如下所示: 对于ICM 部署的实例,使用带有-machine 和-interactive 选项的 icmexec命令,打开正在运行该实例的容器的bash shell ,例如: icm exec -command bash -machine MYIRIS-AM-TEST-0004 -interactive 然后,您可以在容器文件系统上创建目录。 对于任何容器化实例,无论是授权版还是社区版,请使用 docker exec -it container_name bash 命令打开该容器的bash shell (社区版的容器名称是try-iris )。然后在容器文件系统上创建4个目录 对于InterSystems Learning Labs(学习实验室),在集成IDE中使用命令行终端,在共享文件夹下创建新文件夹;您可以在/home/project/shared 路径下的Management Portal(管理门户)中浏览这些文件夹。 对于已安装的实例,在本地文件系统上创建4个目录。 本文本假定以下是Windows 系统上已安装实例的目录路径;替换您创建的实际目录的路径。 c:\Practice\In c:\Practice\Out c:\Practice\PDFsOut c:\Practice\Work 在管理门户中,创建一个新的production: 选择Interoperability( 互操作性),如果出现提示,请选择一个支持互操作的命名空间。 选择Interoperability ( 互操作性)> 列表 > Production。 如果一个产品当前正在命名空间中运行,请打开它,然后选择停止。返回产品列表页面。 选择新建,创建一个新的产品。 指定包名称(例如 TEST)和production名称(例如 FileProd)。您将创建可用于任何目的的通用production。选择OK创建该产品。 向该产品添加一项业务服务(BS)和两项业务操作(BO): 选择服务旁边的加号符号以显示业务服务向导。 在服务类下拉菜单,选择EnsLib.File.PassthroughService 。 指定服务名FileService。 清空立即启用复选框。 选择确定。 对两项业务操作(BO)重复这些步骤。从选择操作旁边的 加号符号以显示业务操作向导开始。对这两项操作使用 EnsLib.File.Pa ssthroughOperation 类。将一项操作名称命名为WriteFileOp ,另一项命名为WritePDFsOp。 配置这项业务服务(BS)和两项业务操作(BO): 选择您在产品配置图中创建的业务服务(BS),并在设置选项卡: a. 选择启用复选框。 在文件路径字段,输入c:\Practice\In。 在存档路径字段,输入c:\Practice\Work。 在工作路径字段,输入c:\Practice\Work。 在接收消息的目标名称字段,选择WriteFileOp。 其他字段为默认值。 选择应用。 为两项业务操作(BO)中的每一项指定设置。选择产品图中的操作,然后: a. 选择启用复选框。 在文件路径字段,对于 WriteFileOp 操作输入c:\Practice\Out,对于 WritePDFsOp 操作输入 c:\Practice\PDFsOut。 其他字段为默认值。 选择应用。 启动Production & 跟踪消息 启动该production后,您将复制一个文件到 FileService 的导入目录。您能查看 WriteFileOp 的导出目录中的文件,并通过该production跟踪消息。请注意,运行这个production时不使用WritePDFsOp 操作。要启动production并跟踪消息: 通过选择开始启动产品。 将任一文件复制到c:\Practice\In 目录。如果该产品配置正确,应该会出现以下情况: 几秒钟后,文件从 c:\Practice\In 目录移动到 c:\Practice\Work 目录。文件名称规范将后附时间戳。例如, 如果原始文件是hello.txt,工作文件可能名称为hello.txt_2018-05-07_17.24.57.056 。 文件的新版本被写入c:\Practice\Out 目录。它还附加了一个时间戳。 产品图中的圆圈应保持绿色。如果圆圈变成红色,则表示产品中存在错误。遍历前面的步骤并确保这些目录存在。 在production配置页面选择FileService,选择消息选项卡。它列出了通过该产品的每条消息。选择转到消息查看器。 在消息查看器中选择一条消息,然后选择跟踪选项卡。它将显示从FileService 转到WriteFileOp 操作的消息。 选择正文选项卡,它将显示消息类型和消息中的字段: 请注意,消息类型是Ens.StreamContainer,其中一个字段是OriginalFilename。 将路由器添加到Production中 在本步骤中,将向产品添加路由业务流程和规则。然后,您将一个文件复制到导入目录,并查看显示消息通过路由器的跟踪。在Management Portal(管理门户)中: 选择Interoperability( 互操作性) >配置>Production进入Production 配置 页面,然后选择流程旁边的加号符号以显示业务流程向导。在向导中: 在业务流程类下拉菜单,选择EnsLib.MsgRouter.RoutingEngine。 选择自动创建规则复选框。 指定业务流程名称为FileRouter。 清空Enabled( 启用)复选框。 选择确定。 在对话框中选择OK以批准规则类名称 在Production配置页面选择FileRouter,然后在设置选项卡: a. 选择启用复选框。 选择应用。 选择业务规则名称右侧的放大镜。这将启动规则编辑器,并显示在您创建业务流程时自动生成的规则。 在规则编辑器中,您将创建一条规则,将PDF 文件发送到WritePDFsOp 操作,并将所有其他文件发送到WriteFileOp 操作。规则如下所示 要创建此规则: 双击规则中的 constraint (约束)值。 在 源 字段输入FileService。 在消息类字段输入Ens.StreamContainer。 选择OK。 在 规则辅助中选择rule( 规则) 然后选择when。 选择 when 条件值,并在规则图上方的文本框内输入Document.OriginalFilename Contains ".pdf",然后选择确定。 选择图中的 when 子句,然后在规则辅助选择 send(发送)。 双击 target 值并选择WritePDFsOp 配置项。 选择图中的 when 子句,然后在规则辅助 选择 otherwise。 选择图中的 otherwise 子句,然后在规则辅助选择 send( 发送)。 双击 send 子句的 target 值并选择WriteFileOp 配置项。 选择保存。 返回到Production配置页面,选择FileService 并在 Settings 选项卡: 选择FileRouter 为接收消息的目标名称。 清空WriteFileOp 复选框。 然后选择应用。 您的productioin现已完成。FileService 将所有消息发送到FileRouter 业务流程(BP)。FileRouter 将根据规则将消息发送到WritePDFsOp 或WriteFileOp 操作。 如果你将hello.pdf 复制到c:\Practice\In 目录,它将被发送到 c:\Practice\PDFsOut 目录,但是,如果您复制test.txt 到c c:\Practice\In 目录,它将被发送到c:\Practice\Out 目录。您还可以查看消息跟踪,消息跟踪可以显示通过文件路由器的消息路径。例如,hello.pdf 的跟踪可能如下: 了解有关互操作性产品的更多信息 有关产品的更多信息,请参阅: 介绍互操作性production 开发产品production 配置production 制定业务规则
文章
Louis Lu · 九月 22, 2021

IRIS 2021 技术文档 First Look 5-- 技术概要:InterSystems SQL

技术概要(First Look)有助于您了解在InterSystems IRIS ®数据平台中如何使用SQL:标准的SQL功能、特有功能以及如何快速上手使用。 要体验技术概要(First Look)的所有内容 ,您可以在InterSystems IRIS的免费评估实例上执行相关操作 ,请参阅InterSystems First Looks(《InterSystems 技术概要》)。 1. InterSystems SQL: 特性和性能 InterSystems IRIS 提供高性能、功能完善的 SQL。在 InterSystems IRIS 中使用SQL,包括在单个CPU内核上运行查询,到使用数十个内核的CPU上并行执行查询,已至在InterSystems IRIS服务器集群上运行分布式查询。 在InterSystems IRIS中,可以使用 SQL 的范围包括: 联接(Joins) 灵活、高性能索引 聚合函数和分组 以SQL或InterSystems ObjectScript (以下简称“ObjectScript” )编写的存储过程 JDBC和ODBC连接 自动并行查询 透明分布式查询 InterSystems SQL提供了强大的工具来实现最佳的SQL查询性能。其中一个工具是使用压缩位图索引:使用紧凑、高度有效的结构和向量化的CPU指令, InterSystems SQL可以只用单个内核即可执行每秒数十亿行的聚合操作以及检查逻辑判断条件。本指南的后续内容将提供位图索引的示例。 想要快速尝试InterSystems IRIS的SQL功能吗?查看SQL QuickStart! 2. 演示:SQL Shell 可以通过各种应用程序接口、交互式客户端和标准协议在InterSystems IRIS中执行SQL ,包括: 用于交互式SQL语句执行的InterSystems IRIS SQL Shell ODBC和JDBC客户端、交互式应用(例如, SQuirreL SQL或WinSQL )或通过将InterSystems IRIS驱动程序嵌入使用的应用程序 InterSystems IRIS管理门户中的System Explorer,为执行SQL提供了交互式的Web界面 在ObjectScript类中执行嵌入式SQL或动态SQL 如果在阅读本指南后,想了解这些主题的更多有关信息,请参阅下面的“了解有关InterSystems SQL的更多信息”。 此示例向您展示如何使用SQL Shell交互式执行SQL语句,或执行文件中的SQL语句。 2.1 用前须知 要使用该程序,需要一个正在运行的InterSystems IRIS实例。可以选择多种类型的已授权的免费评估实例;该实例不必存储在正在运行的系统(尽管它们可以互相进行网络访问)。如何部署每个类型的实例(如果您还没有要使用的实例)的有关信息,请参阅 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的Deploying InterSystems IRIS(部署 InterSystems IRIS)。 还需要从GitHub存储库https://github.com/intersystems/FirstLook- SQLBasics获取本指南的实用程序文件。应该克隆存储库来下载以下文件: stock_table_demo_one.sql ,其中包含用于创建和加载小型( 20行)存量数据的表格的SQL语句 stock_table_demo_two.csv ,其中包含一百万行存量表数据 Loader.xml ,包含实用程序方法的类文件,用于将数据从stock_table_demo_two.csv加载到InterSystems IRIS表中 注意: stock_table_demo_two.csv 非常大 ,要下载它之前需要安装Git Large File Storage。 必须通过该实例访问FirstLook-SQLBasics源。下载文件的程序取决于所使用的实例类型,如下所示: 如果使用的是ICM部署的实例: 1.使用具有-machine 和-interactive 选项的 icm ssh 命令在储存该实例的节点上打开默认shell ,例如: icm ssh -machine MYIRIS-AM-TEST-0004 -interactive 2. 在Linux命令行上,使用以下命令之一将存储库克隆到该实例的数据存储卷(data storage volume)。 例如,对于部署在Azure上的配置,数据卷的默认装入点为 /dev/sdd ,因此应使用如下命令: $ git clone https://github.com/intersystems/FirstLook-SQLBasics /dev/sdd/FirstLook-SQLBasics 或者使用命令: $ wget -qO- https://github.com/intersystems/FirstLook-SQLBasics/archive/master.tar.gz | tar xvz -C /dev/sdd 这些文件现在可以通过容器文件系统的/irissys/data/FirstLook-SQLBasics 目录被InterSystems IRIS获取。 如果您使用的是通过其他方式部署的容器化实例(授权的版本或社区版本): 1. 在主机上打开Linux命令行。(如果您在云节点上使用社区版本 ,请使用SSH连接到节点,如部署和浏览InterSystems IRIS中所述。) 2. 在Linux命令行上,使用git clone或wget命令,如上所述,将存储库克隆到加载为容器中的数据卷的存储位置。 对于社区版实例,可以克隆到该实例的%SYS 目录(社区版实例指定的配置数据存储的位置)。在Linux文件系统上,此目录为/opt/ISC/dur。该文件可以在容器文件系统的/ISC/dur/FirstLook-SQLBasics目录下被InterSystems IRIS获取。 对于授权的容器化实例,选择加载为容器中的数据卷的存储位置(包括durable%SYS 目录,如果使用的话)。例如,如果您的docker run命令包括选项 -v /home/user1:/external,然后将存储库克隆到/home/user1 ,这些文件在容器文件系统上的/external/FirstLook-SQLBasics目录中可被Inter- Systems IRIS获取。 如果您使用的是InterSystems Learning Labs实例: 1. 在集成的IDE中打开命令行终端。 2. 将目录更改为/home/project/shared ,并使用 git clone命令克隆存储库: $ git clone https://github.com/intersystems/FirstLook-SQLBasics 该文件夹添加到“Shared”下左侧的Explorer面板,且该目录可在InterSystems IRIS 选择路径的 /home/project/shared下被获取。 如果您使用的是已安装的实例: 如果实例的主机是安装有GitHub Desktop和GitHub Large File Storage 的Windows系统: a. 在主机的web浏览器中转到 https://github.com/intersystems/FirstLook-SQLBasics。 b. 选择Clone or download ,然后选择 Open in Desktop。 这些文件可在GitHub目录中被InterSystems IRIS 获取,例如 C:\ Users\ User1\ Documents\ GitHub\ FirstLook-SQLBasics。 如果主机是Linux系统,只需使用Linux命令行上的git clone命令或wget命令将存储库克隆到您选择的位置即可。 2.2 使用SQL脚本文件创建和填充表 为达到演示目的,我们使用一个SQL脚本文件,stock_table_demo_one.sql,来创建并加载包含几行示例数据的表。 创建和加载表格: 打开InterSystems 终端terminal。将看到如下交互式提示: USER> 此提示表示您目前在 USER 命名空间(namespace)中,默认情况下该空间为空,可供客户自由使用。从该提示开始,可以执行ObjectScript。 通过输入如下命令立刻打开SQL Shell DO $SYSTEM.SQL.Shell() 这将输出以下内容: SQL Command Line Shell The command prefix is currently set to: <<nothing>>. Enter q to quit, ? for help. [SQL]USER>> 将当前SQL数据库方言设置为IRIS: SET DIALECT=IRIS 要运行stock_table_demo_one.sql中的语句,请输入命令 RUN <Path>stock_table_demo_one.sql 其中Path是放置文件的位置(请参阅前面的用前须知)。系统会提示您为日志文件指定名称,日志文件包含文件中的语句及其输出结果、如何处理错误以及语句分隔符。接受所有默认值。 语句创建一个表格并插入20行。文件的前几行是: CREATE TABLE FirstLook.StockTableDemoOne (ClientID INTEGER, BrokerID INTEGER, Symbol VARCHAR(10), TransactionType VARCHAR(4), TransactionDate TIMESTAMP,Quantity INTEGER, Price DECIMAL(15,2), CommmissionRate DECIMAL(15,2)) GO INSERT INTO FirstLook.StockTableDemoOne (ClientID, BrokerID, Symbol, TransactionType, TransactionDate, Quantity, Price, CommmissionRate) VALUES (29834783, 3103, 'RTYU', 'SELL', '2016-01-03', 342, 5.05, 3.25) GO 当脚本运行时,在处理每个SQL语句后将看到输出结果: 1. INSERT INTO FirstLook.StockTableDemoOne (ClientID, BrokerID, Symbol, 2. TransactionType, TransactionDate, Quantity, 3. Price, CommissionRate) 4. VALUES (92609349, 3103, 'HWVT', 'BUY', '2017-10-25', 1500, 451.09, 3.25) 1 Row Affectedu 处理完所有语句后, SQL Shell会列出编译的语句数量以及报告的错误和警告,并报告已用时间: Statements .................compiled: 21 .....with errors reported: 0 ...with warnings reported: 0 Elapsed time: .125181 seconds 2.3 在SQL Shell中直接运行查询 有了已填充的表后,可以对它运行查询。可以使用单行或多行模式来执行此操作,但后者可能更方便。 若要进入多行模式,请根据提示按Enter键。将看到处于多行模式的确认信息。 输入以下SQL语法,逐行输入。关键字GO 指示shell执行查询并退出多行模式: SELECT BrokerID, TO_CHAR((Quantity * Price),'9,999,999.99') as SubTotal, TransactionDate FROM FirstLook.StockTableDemoOne WHERE TransactionType='SELL' ORDER BY SubTotal DESC GO 您输入的语句将与SQL Shell呼应,后附查询结果。 BrokerID SubTotal TransactionDate 5001 302780.00 2017-11-06 09:51:24.735 5002 92350.00 2018-01-15 22:21:17.638 3103 57645.00 2017-09-24 19:36:43.079 3103 45015.00 2016-10-31 19:21:08.913 5001 23180.50 2017-07-31 23:05:49.83 5001 13113.60 2015-11-13 22:13:49.457 5001 12636.00 2015-10-13 05:50:23.209 3103 1727.10 2016-01-03 13:59:01.098 1009 1693.50 2016-01-15 18:18:15.346 在查询结果后,您将看到准备和执行语句所需时间的信息: 9 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0625s/47683/263292/0ms execute time(s)/globals/cmds/disk: 0.0006s/64/2903/0ms cached query class: %sqlcq.USER.cls47 准备步骤包括从一条SQL语句的语法到生成可执行代码。此代码被缓存,以供重复使用,因此一条语句通常仅完全准备一次。后续准备只需要使用语句文本的hash来定位已经缓存的代码。 执行步骤包括执行针对查询生成的代码并返回其结果。在每个步骤的列表中都包含以下指标: 每个步骤所花费的时间。 Globals计数,即为准备或执行SQL语句而引用InterSystems IRIS存储的数量。如需进一步了解全局有关信息,请参阅Orientation Guide for Server-Side Programming(《服务器端编程入门指南》)中的“Introduction to Globals (Globals简介)”一章。 为准备或执行SQL语句而执行的ObjectScript命令的数目。 显示结果的结尾是缓存的查询类(cached query class),这是首次准备语句时生成的缓存代码的ObjectScript类。 3. 也可以使用聚合函数和 GROUP BY。请注意,可以对聚合函数的别名排序: SELECT BrokerID, TO_CHAR(SUM(Quantity * Price), '9,999,999.99') as SubTotal FROM FirstLook.StockTableDemoOne GROUP BY BrokerID ORDER BY SubTotal DESC GO BrokerID SubTotal 3103 868,993.60 1009 808,453.50 5001 593,242.82 5002 187,560.00 4 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.1665s/45832/237712/77ms execute time(s)/globals/cmds/disk: 0.0025s/122/2434/2ms cached query class: %sqlcq.USER.cls9 3. 演示:使用位图索引提高查询性能 如果您正在使用大型数据集,寻找改善查询性能的方法,位图索引是您可以使用的几种方法之一。 如果一个表有一个或多个字段,字段的可能值集合较小,则创建位图索引特别适合。 有关位图索引运行的详细信息,请参阅InterSystems SQL Optimization Guide(《InterSystems SQL优化指南》)的 Bitmap Indices(位图索引)章节。 在本演示中,您将看到在股票交易数据的百万行数据表格中创建目标位图索引引发的变化。您将使用几个简单的 ObjectScript 命令;很容易地从SQL Shell内无缝访问 ObjectScript 类库。 要运行演示: 按照“使用SQL脚本文件创建和填充表格”(Creating and Populating a Table With a SQL Script File)所述,在终端中启动SQL Shell。 创建表: CREATE TABLE FirstLook.StockTableDemoTwo (ClientID INTEGER, BrokerID INTEGER, Symbol VARCHAR(10), TransactionType VARCHAR(4), TransactionDate TIMESTAMP, Quantity INTEGER, Price DECIMAL(15,2), CommissionRate DECIMAL(15,2)) 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0063s/1811/22260/0ms execute time(s)/globals/cmds/disk: 0.2138s/76495/655985/76ms cached query class: %sqlcq.USER.cls1 导入Loader类( Loader.xml文件)。OBJ前缀表示 SQL Shell 按照 ObjectScript 处理以下命令; “c”标志指示InterSystems IRIS编译代码, “k”标志确保源代码存储在活动命名空间(active namespace)中。 OBJ DO $ system.OBJ.Load ("< Path > Loader.xml", "ck") 其中Path是放置文件的位置(请参阅用前须知)。将输出如下结果: Load started on 04/19/2018 15:17:53 Loading file C:\Users\user\repos\FirstLook-SQLBasics\Loader.xml as xml Imported class: FirstLook.Loader Compiling class FirstLook.Loader Compiling routine FirstLook.Loader.1 Load finished successfully. 要将stock_table_demo_two.csv中的数据加载到表中,请在终端中运行以下命令: OBJ WRITE ##class(FirstLook.Loader).LoadStockTableCSV("<Path>stock_table_demo_two.csv") 其中Path是放置文件的位置。此命令的输出结果1000000仅表示已加载100万行。 运行以下查询: SELECT DISTINCT BrokerID FROM FirstLook.StockTableDemoTwo 输出结果显示,可能的经纪人ID的数量非常小,因此该字段是位图索引的好选择。 BrokerID 115 107 101 114 119 104 109 108 20 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0645s/43430/197693/9ms execute time(s)/globals/cmds/disk: 1.2569s/2000039/9001314/0ms cached query class: %sqlcq.USER.cls10 6. 要在添加位图索引之前查看涉及BrokerID字段的COUNT查询的性能,请运行以下查询: SELECT BrokerID, COUNT(*) As Transactions FROM FirstLook.StockTableDemoTwo GROUP BY BrokerId ORDER BY Transactions DESC BrokerId Transactions 103 50386 118 50304 107 50247 112 50207 101 50174 109 50088 115 50088 104 50048 111 50031 105 50008 113 49996 119 49942 114 49919 116 49894 110 49888 108 49882 102 49843 120 49768 106 49742 117 49545 20 Rows(s) Affected 观察查询返回结果后显示的查询性能统计信息:所用总时间(包括准备和执行时间)约为0.65秒。 statement prepare time(s)/globals/cmds/disk: 0.0695s/45048/225490/13ms execute time(s)/globals/cmds/disk: 0.5878s/1000250/11002218/0ms cached query class: %sqlcq.USER.cls7 7. 在BrokerID上添加位图索引: CREATE BITMAP INDEX BrokerIDIdx ON TABLE FirstLook.StockTableDemoTwo (BrokerID) 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0056s/1723/15958/0ms execute time(s)/globals/cmds/disk: 0.9805s/2071557/18505697/1ms cached query class: %sqlcq.USER.cls11 8. 运行与上述相同的SELECT查询。请注意性能提升:在下面的示例中,查询总共花费了大约0.35秒,减少了近50%。 SELECT BrokerID, COUNT(*) As Transactions FROM FirstLook.StockTableDemoTwo GROUP BY BrokerId ORDER BY Transactions DESC ... statement prepare time(s)/globals/cmds/disk: 0.0573s/45585/231374/0m execute time(s)/globals/cmds/disk: 0.2926s/622/15004397/0ms cached query class: %sqlcq.USER.cls1 4. 了解有关InterSystems SQL的更多信息 要了解有关SQL和InterSystems IRIS的更多信息,请参阅: 4.1 介绍材料 Using InterSystems SQL(使用InterSystems SQL) InterSystems SQL Reference(InterSystems SQL参考书目) InterSystems SQL Overview(InterSystems SQL概述) 4.2 SQL开发 SQL –Things You Should Know (SQL-您应该知道的事情) Developing with InterSystems Objects and SQL(使用InterSystems Objects和SQL开发) 4.3 查询优化 First Look: Optimizing SQL Performance with InterSystems IRIS(技术概要:使用InterSystems IRIS优化SQL性能) InterSystems SQL Optimization Guide(InterSystems SQL优化指南) Academy – Optimizing SQL Performance(学院派–优化SQL性能) Optimizing SQL Queries(优化SQL查询) 4.4 分片和可扩展性 First Look: Scaling for Data Volume with Sharding(技术概要:带分片的数据卷扩展) Scalability Guide(可扩展性指南) 4.5 SQL Search SQL Search First Look: SQL Search with InterSystems IRIS(技术概要:使用InterSystems IRIS进行) Using InterSystems SQL Search(使用InterSystems SQL Search) Creating iFind Indices for Searching Text Fields(创建用于搜索文本字段的iFind索引) 4.6 JDBC First Look: JDBC and InterSystems IRIS(技术概要:JDBC和InterSystems IRIS) Using Java JDBC with InterSystems IRIS (documentation)(使用InterSystems IRIS进行Java JDBC <文档>) Java Overview(Java概述) Using JDBC with InterSystems IRIS (online learning)(在InterSystems IRIS中使用JDBC <在线学习>)
文章
jieliang liu · 九月 22, 2021

IRIS 2021 技术文档 First Look 14-- JDBC 和 InterSystems 数据库

本文档介绍了如何使用 InterSystems JDBC 驱动程序连接到 InterSystems IRIS®数据平台实例,这样您就可以在 InterSystems IRIS 中使用 Java。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 JDBC:如何在 InterSystems IRIS 中使用它 InterSystems 提供了完全兼容的(JDBC 4.2)、纯 Java、type 4 JDBC 驱动程序,它是一个独立的 JAR 文件,没有任何依赖性。如果您已经熟悉 JDBC,并且安装了 JDK 1.8,那么您需要做的就是将 JDBC 驱动程序添加到本地 CLASSPATH 中(请参见 JDBC:Exploring It [《JDBC:探索它》] )。JDBC URL(连接字符串)是: jdbc:IRIS://ipAddress:superserverPort/namespace 其中的变量表示 InterSystems IRIS 实例主机的 IP 地址、实例的超级服务器端口和实例上的命名空间。 如果您连接到本地计算机上的一个实例(使用主机名 localhost 或 IP 地址 127.0.0.1),该连接可以使用一种特殊的、高性能的本地连接,称为共享内存连接(shared memory connection)。有关共享内存连接(shared memory connection)的更多信息,请参见 "JDBC:What's Unique about Shared Memory Connections(《JDBC: 共享内存连接的独特之处》)"。 本文档的重点是让您体验一下在 InterSystems IRIS 中使用 JDBC,而不是让您陷入细节困境 ,所以我们保持了简单的探索。但是,当您把 InterSystems IRIS 引入您的生产系统时,您需要做很多不同的事情,例如(但不限于)安全性方面。所以请确保不要把这种对 InterSystems IRIS 的探索与真实的情况相混淆! 本文档末尾提供的参考资料将使您对在生产中使用 JDBC 与 InterSystems IRIS 的情况有一个很好的了解。 JDBC:InterSystems IRIS Java 连接选项的一部分 InterSystems IRIS JDBC 驱动程序是 InterSystems IRIS 的核心 Java 组件,支持传统的关系(SQL)访问。它还为使用 InterSystems IRIS Native API for Java 的 Java 调用提供连接机制,这些调用可以访问本机存储格式中的数据。对于基于对象的 Java 集成,InterSystems IRIS 还提供一个单独的功能------InterSystems IRIS XEP 组件(InterSystems IRIS XEP component)。 综上所述,InterSystems IRIS 提供了一组独特的功能,可以使用相同的物理连接和事务环境来使用多个范例(本机[native]、关系[relational]和面向对象[object-oriented])操作数据。对于更复杂的应用程序,InterSystems 完全支持 Hibernate。支持所有这些连接形式的------InterSystems IRIS XEP、Hibernate 以及 InterSystems IRIS Spark 连接器(Connector)------是 InterSystems IRIS JDBC 驱动程序。 技术概要: JDBC 和 InterSystems 数据库 1 JDBC:探索它 JDBC: 共享内存连接(Shared Memory Connections)的独特之处 与其他数据库平台一样,到远程 InterSystems IRIS 实例的 JDBC 连接是通过 TCP/IP 进行的。为了最大限度地提高性能,InterSystems IRIS 还提供了 Java 共享内存连接(shared memory connection)。与 InterSystems IRIS 实例在同一计算机上运行的许多 Java 应用程序都可以使用共享内存连接(shared memory connection)。 共享内存连接(shared memory connection)是一个临时设备,支持虚拟内存,由 JDBC 客户端和运行在同一物理计算机上的 InterSystems IRIS 实例共享。此外,这些连接不需要对内核网络堆栈进行潜在的昂贵调用。通过使用直接从 JDBC 客户端到 InterSystems IRIS 的通道,它们最终为 JDBC 操作提供了低延迟和高吞吐量。 有关共享内存(shared memory connection)的详细信息,请参见 Using Java with the InterSystems JDBC Driver(《在 InterSystems JDBC 驱动程序中使用 Java》)中的 "Shared Memory Connections(共享内存连接)"。 JDBC:探索它 我们开发了一个演示,向您展示如何使用 JDBC 和 InterSystems IRIS------以及这是多么地简单。 请注意,这段代码并没有演示 InterSystems Java 共享内存连接(shared memory connection)的性能提升,因为它无法处理共享内存连接(shared memory connection)可以高效处理的大量数据。 想试试 InterSystems IRIS Java 开发和互操作性功能的在线视频演示吗?请查看 Java QuickStart(Java 快速入门)! 用前须知 要使用该程序,您需要在一个系统上工作,安装 JDK 1.8 版本和您选择的 Java IDE,并连接一个正在运行的 InterSystems IRIS 实例。您对 InterSystems IRIS 的选择包括多种已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。有关如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 Java IDE 中的信息,将 IDE 连接到您的 InterSystems IRIS 实例。对于这个演示,您可以连接到 USERnamespace,如下面的代码所示,或者您可以指定在已安装的实例中创建的另一个命名空间。 您还需要将 InterSystems IRIS JDBC 驱动程序 intersystems-jdbc-3.0.0.jar 添加到您的本地 CLASSPATH。您可以从 https://github.com/intersystems/quickstarts-java/tree/master/lib 下载这个文件。如果您已经在您的本地计算机或您能访问的另一台计算机上安装了 InterSystems IRIS,您可以在 install-dirdevjavalibJDK18 中找到该文件,其中 install-dir 是 InterSystems IRIS 的安装目录。 尝试示例代码 将示例代码剪切并粘贴到您的 IDE 中,使用 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE 》)中的connection settings described for your instance(为您的实例描述的连接设置)更新 url 和连接(connecttion)变量以及用户名和密码。 . import java.sql.*; public class JDBCSample { ​ public static void main(String[] str) throws Exception { String url = "jdbc:IRIS://127.0.0.1:1972/USER"; ​ Class.forName("com.intersystems.jdbc.IRISDriver"); ​ Connection connection = DriverManager.getConnection(url,"_SYSTEM","SYS"); // Replace _SYSTEM and SYS with a username and password on your system ​ String createTable = "CREATE TABLE People(ID int, FirstName varchar(255), LastName varchar(255))"; String insert1 = "INSERT INTO People VALUES (1, 'John', 'Smith')"; ​ String insert2 = "INSERT INTO People VALUES (2, 'Jane', 'Doe')"; String query = "SELECT * FROM People"; ​ Statement statement = connection.createStatement(); statement.executeUpdate(createTable); statement.executeUpdate(insert1); statement.executeUpdate(insert2); ​ ResultSet resultSet = statement.executeQuery(query); System.out.println("Printing out contents of SELECT query: "); while (resultSet.next()) { ​ System.out.println(resultSet.getString(1) + ", " + resultSet.getString(2) + ", " + resultSet.getString(3)); ​ } ​ resultSet.close(); statement.close(); connection.close(); ​ } ​ } 如果连接和查询已经成功完成,您应该会看到一个控制台窗口(console window),其中包含 SELECT 查询的结果。 4 了解有关 JDBC 的更多信息 要了解有关 JDBC、InterSystems IRIS 中的其他 Java 互操作性技术和其他相关主题的更多信息,请参见: Using Java JDBC with InterSystems IRIS(《在 InterSystems IRIS 中使用 Java JDBC》)中的 "InterSystems Java Connectivity Options(InterSystems Java 连接选项)"------对JDBC 驱动程序支持的所有 InterSystems IRIS Java 技术的概述。 Using Java with the InterSystems JDBC Driver(《在 InterSystems JDBC 驱动程序中使用 Java》)------InterSystems 文档:step-by-step instructions for using JDBC(《使用 JDBC 的详细说明》)。 First Look: XEP Object Persistence with InterSystems IRIS(《技术概要: 使用 InterSystems IRIS 持久化 XEP 对象》)------InterSystems 文档:Java XEP First Look(《Java XEP 技术概要》) First Look:InterSystems IRIS Native API for Java(《技术概要: InterSystems IRIS Native API for Java》)------InterSystems 文档:InterSystems IRIS Native API First Look(《InterSystems IRIS Native API 技术概要》) Java Overview(《Java 概述》)------InterSystems 在线学习:介绍视频 Persisting Java Objects with InterSystems XEP(《使用 InterSystems XEP 持久化 Java 对象》)------InterSystems 文档:step-by-step instructions for using XEP(《使用 XEP 的详细说明》) InterSystems Implementation Reference for Java Third Party APIs (《Java 第三方 API 的 InterSystems 实施参考》)------InterSystems 文档:connecting to InterSystems IRIS using JDBC, Hibernate, and Spark(《使用 JDBC、Hibernate 和 Spark 连接 InterSystems IRIS》)。 Using the InterSystems Spark Connector(《使用 InterSystems Spark 连接器》)------InterSystems 文档:using InterSystems IRIS as an Apache data source(《使用 InterSystems IRIS 作为 Apache 数据源》) Hibernate and JDBC compared(《Hibernate 和 JDBC 的比较》)------栈溢出(Stack Overflow)的文章
文章
jieliang liu · 九月 22, 2021

IRIS 2021 技术文档 First Look 9--ADO.NET 和 InterSystems 产品

技术概要:ADO.NET 和 InterSystems 产品 本技术概要(First Look)解释了如何通过 InterSystems ADO.NET Managed Provider 连接到 InterSystems IRIS®数据平台。一旦根据本指南完成操作,就意味着您已经配置了一个 Visual Studio 项目来使用 InterSystems.Data.IRISClient.dll 程序集,建立了到 InterSystems IRIS 的 ADO.NET 连接,从您的 .NET 应用程序运行多个 SQL 语句,并在 InterSystems IRIS 系统管理门户(InterSystems IRIS System Management Portal)中确认这些语句的效果。 为了让您体验一下 ADO.NET Managed Provider,而又不陷入细节的困境,我们会确保这一探索简洁可行。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您将 ADO.NET 引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 ADO.NET 的探索与真实的东西混淆起来! 本文档末尾提供的参考资料将使您对在生产中使用 ADO.NET 所涉及的内容有一个很好的了解。 有关 ADO.NET 的更多文档,请参见结尾处的 Learn More About ADO.NET(了解更多有关 ADO.NET 的信息)。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 为什么 ADO.NET 很重要 ADO.NET 是来自 Microsoft .NET Framework 的数据访问技术,提供对数据源的访问。它用于建立数据库连接,并为 .NET Framework 程序员提供一种标准、可靠的方式,来连接到多种类型的数据源或使用 SQL 对它们进行操作。通过 ADO.NET Managed Provider 连接到 InterSystems IRIS 很简单,特别是如果您以前使用过 ADO.NET。从 .NET 应用程序建立到 InterSystems IRIS 的 ADO.NET 连接,允许您从 .NET 应用程序对 InterSystems IRIS 数据库运行 SQL 命令。 如果您是 InterSystems IRIS 的新手,但熟悉 .NET 和 SQL,您可以立即使用现有的专业知识来帮助您熟悉数据库平台。您可以在开发环境中测试 ADO.NET 连接和 SQL 命令,只需几行代码。 ADO.NET 和 InterSystems IRIS InterSystems IRIS 是完全符合 ADO.NET 规范的实现。InterSystems ADO.NET Managed Provider 提供对数据的简单关系访问。它处理来自应用程序的 ADO.NET 方法调用,并向 InterSystems IRIS 提交 SQL 请求。然后将结果返回给调用的应用程序------在本例中,就是您的 .NET 应用程序。 通过 ADO.NET 连接到 InterSystems IRIS 是一个非常简单的过程。 为了使用 InterSystems IRIS ADO.NET 功能,您必须首先将 InterSystems.Data.IRISClient.dll 程序集作为依赖项添加到 Visual Studio 项目中。确认一些设置后,使用我们的示例代码建立到 InterSystems IRIS 的 ADO.NET 探索 ADO.NET 连接,并执行 SQL 查询。请注意,InterSystems.Data.IRISClient.dll 程序集自始至终都是使用 .NET 管理代码实现的,这使得在 .NET 环境中部署它很容易。它是线程安全(thread-safe)的 ,可以在多线程的 .NET 应用程序中使用。 探索 ADO.NET 我们开发了一个简短的演示,向您展示如何使用 ADO.NET 和 InterSystems IRIS。(想试试 InterSystems IRIS .NET 开发和互操作性功能的在线视频演示?请看.NET QuickStart(.NET 快速入门)!) 用前须知 要使用这个程序,您需要一个安装了 .NET 框架和 Visual Studio 的 Windows 系统,以及一个运行中的 InterSystems IRIS 实例来连接。您对 InterSystems IRIS 的选择包括多种类型的已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。有关如何部署每种类型的实例的信息(如果您还没有可使用的实例) ,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE 中的信息将 Visual Studio 连接到您的 InterSystems IRIS 实例。 配置 Visual Studio 项目 在 Visual Studio 主菜单中,通过选择 File(文件) > New (新的)> Project(项目)创建一个新项目。在出现的对话框中,点击 Visual C# 选项,并选择 Console App (.NET Framework)(控制台应用程序(.NET 框架))。对于 Name(名称) 字段,输入 ADONET。点击 OK(確定)。这将使用 .NET Framework 创建一个新的控制台(console)应用程序。 下一步,在 Visual Studio 主菜单中,选择 Project(项目) > ADONET Properties(ADONET 属性)。在 Target framework(目标框架)下,选择 .NET Framework 4.5(.NET 框架 4.5)。 添加程序集引用 InterSystems.Data.IRISClient.dll 程序集必须安装在您的本地系统上。您可以通过克隆 repo https://github.com/intersystems/quickstarts-dotnet/tree/master/EFPlay/bin/Debug 或从该 repo 下载文件来获取它。如果 InterSystems IRIS 安装在您的本地系统或您可以访问的另一个系统上,则该程序集已经安装在子目录 install-dirdevdotnetbinv4.5 中,其中 install-dir 是该实例的安装目录。 要将 InterSystems.Data.IRISClient.dll 的程序集引用添加到项目: 从 Visual Studio 主菜单中,选择 Project(项目) > Add Reference(添加引用)... 在出现的窗口中,点击 Browse(浏览).... 浏览到 InterSystems.Data.IRISClient.dll 文件的位置。 选择文件并点击 Add(添加)。 点击 OK(確定)。 在 Visual Studio Solution Explorer 中, InterSystems.Data.IRISClient.dll 程序集现在应该列在 Reference(引用)下。 探索 ADO.NET 通过 ADO.NET 连接 现在,您可以从 .NET 应用程序连接到 InterSystems IRIS 了。InterSystems ADO.NET Managed Provider 的连接字符串是由定义连接属性的键/值对组成的。连接字符串的语法是: Server=host_IP; Port=superserverPort; Namespace=namespace; Password=password; User ID=username; 其中的变量表示 InterSystems IRIS 实例主机的 IP 地址、实例的超级服务器端口、实例上的命名空间和实例的凭据(credentials)。这与您在连接 Visual Studio 到您的实例时使用的信息相同,如用前须知中所述。 将其粘贴到 Visual Studio 后,在随后的代码中更新该信息。您可以将命名空间设置为预定义的命名空间 USER,如所示,或者设置为您在已安装的实例上创建的另一个命名空间。 using System; ​ using InterSystems.Data.IRISClient; ​ namespace ADONET ​ { ​ class Program ​ { ​ static void Main(string[] args) ​ { ​ String host = "<host>"; String port = "<port>"; ​ String username = "<username>"; String password = "<password>"; String Namespace = "USER"; ​ IRISConnection IRISConnect = new IRISConnection(); IRISConnect.ConnectionString = "Server = " + host ​ + "; Port = " + port + "; Namespace = " + Namespace ​ + "; Password = " + password + "; User ID = " + username; ​ IRISConnect.Open(); ​ String sqlStatement1 = "CREATE TABLE People(ID int, FirstName varchar(255), LastName varchar(255))"; ​ String sqlStatement2 = "INSERT INTO People VALUES (1, 'John', 'Smith')"; String sqlStatement3 = "INSERT INTO People VALUES (2, 'Jane', 'Doe')"; String queryString = "SELECT * FROM People"; ​ IRISCommand cmd1 = new IRISCommand(sqlStatement1, IRISConnect); IRISCommand cmd2 = new IRISCommand(sqlStatement2, IRISConnect); IRISCommand cmd3 = new IRISCommand(sqlStatement3, IRISConnect); IRISCommand cmd4 = new IRISCommand(queryString, IRISConnect); ​ //ExecuteNonQuery() is used for CREATE, INSERT, UPDATE, and DELETE SQL Statements cmd1.ExecuteNonQuery(); ​ cmd2.ExecuteNonQuery(); cmd3.ExecuteNonQuery(); ​ //ExecuteReader() is used for SELECT IRISDataReader Reader = cmd4.ExecuteReader(); ​ Console.WriteLine("Printing out contents of SELECT query: "); while (Reader.Read()) ​ { ​ + ", " ​ Console.WriteLine(Reader.GetValue(0).ToString() + ", " + Reader.GetValue(1).ToString() ​ + Reader.GetValue(2).ToString()); ​ } ​ Reader.Close(); cmd1.Dispose(); cmd2.Dispose(); cmd3.Dispose(); cmd4.Dispose(); IRISConnect.Close(); ​ Console.WriteLine("Press any key to continue..."); ​ Console.ReadKey(); ​ } ​ } ​ } 通过点击 Start(开始)按钮,或按 F5 键来运行代码。 如果连接和查询已经成功完成,您应该会看到一个控制台(console)窗口,其中包含 SELECT 查询的结果。 确认管理门户(Management Portal)的变更 接下来,使用以下程序在管理门户(Management Portal)中确认您的结果: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的 URL ,在浏览器中打开您的实例的管理门户(Management Portal)。 如果您不在代码指定的命名空间中,请切换到该命名空间(点击页面顶部 Namespace(命名空间):指示器旁边的 Switch(切换))。 导航到 SQL 页面(System Explorer(系统资源管理器) > SQL),然后点击 Execute Query(执行查询)标签,并粘贴以下 SQL 查询: SELECT ID, FirstName, LastName FROM SQLUser.People 点击 Execute(执行)。该页面应该显示在示例代码中创建的 People 表的内容。 了解更多有关 ADO.NET 的信息 要了解更多有关 ADO.NET、SQL 和 InterSystems IRIS 的信息请参见: Using the InterSystems Managed Provider for .NET(《使用 .NET 的 InterSystems Managed Provider》) Using InterSystems SQL(《使用 InterSystems SQL》) ADO.NET Overview(《ADO.NET 概述》)
文章
jieliang liu · 九月 22, 2021

IRIS 2021 技术文档 First Look 4 ObjectScript 入门

技术概要:ObjectScript 技术概要:ObjectScript 本文档将向您介绍 ObjectScript 编程语言,并提供了几个示例,说明如何使用它来存储和检索来自 InterSystems IRIS®数据平台的数据。本技术概要(First Look)并不试图提供对该语言或其功能的全面概述。您可以使用本文件末尾列出的参考资料,继续您的探索。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 什么是 ObjectScript? ObjectScript 是一种编程语言,用于在 InterSystems IRIS 数据平台上快速开发复杂的业务应用。ObjectScript 源代码被编译成 object 代码,该代码可针对业务应用程序中的典型操作(包括字符串操作和数据库访问)进行高度优化。 ObjectScript 的独特之处之一是它的底层存储结构,即所谓的 globals。Globals 可以被认为是持久的多维稀疏数组。ObjectScript 允许您直接从 globals 访问数据,但也允许您通过其本机 object 和 SQL 支持来访问这些数据。 <span id="2_Try_It:_Storing_and_Retrieving_Data_Us" class="anchor"></span>虽然您可以在 InterSystems IRIS 平台上使用 Java、.NET、node.js 或其他语言编写应用程序,但通过使用该平台的许多 API,您可以使用 ObjectScript 编写高效的、基于服务器的代码,让您对数据有更精细的控制。 试一试:使用 ObjectScript 存储和检索数据 在这篇技术概要(First Look)中,您将学习如何使用 ObjectScript 来: 在 globals 中存储和检索数据。 定义一个类,并实例化、使用和存储该类的 objects。 使用 SQL 查询访问为该类存储的数据,并对结果集进行处理。 正如您将看到的,ObjectScript 使您能够以多种方式存储和访问数据,既强大又灵活。 用前须知 要使用本技术概要(First Look),您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括几种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管您的系统必须能够通过网络访问该实例)。关于如何部署每种类型的实例的信息,如果您还没有一个实例可以使用,请参见(InterSystems IRIS Basics:Connecting an IDE《InterSystems IRIS 基础:连接一个 IDE》)中的Deploying InterSystems IRIS(部署 InterSystems IRIS)。 您也需要知道: 实例的基于 web 的管理门户(Management Portal)的 URL,这是 InterSystems IRIS 的系统管理用户界面。 试一试:使用 ObjectScript 存储和检索数据 如何访问终端(Terminal),InterSystems IRIS 命令行工具。 您的实例的用户名和密码(InterSystems Learning Labs 上的 web 实例不需要)。 您还需要从 InterSystems GitHub repo 下载 ObjectScript 示例代码:https://github.com/intersystems/FirstLook-ObjectScript。 关于如何访问管理门户(Management Portal )或终端(Terminal)的更多信息,请参见InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》) 中的 " InterSystems IRIS Connection Information《InterSystems IRIS 连接信息》)"。尽管您实际上不需要 IDE 来做这些练习,但您可以使用安装了 ObjectScript 扩展的 Studio 或 Visual Studio Code 查看和编辑示例代码 。 导入 ObjectScript 代码示例 首先,将 ObjectScript 代码示例导入 InterSystems IRIS: 从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Classes(类)。 在 Classes 页面上,查看左栏,确保您在 USER 命名空间。您可以把命名空间看作是工作空间或目录。 点击 Import(导入)。 在 Import Classes 的对话框中: a. 如果您的 InterSystems IRIS 实例在远程服务器上运行,请指定是将示例文件下载到远程服务器还是下载到您的本地计算机。 b. 在"File" 或 "Directory"的 Import(导入)区域,点击 File(文件)。 c. 浏览您从 GitHub 下载的 FirstLookObjectScript.xml 文件。 d. 选择 Compile Imported Items(编译导入项)。 e. 对于 Compile Flags(编译标志),指定 cuk。 f. 点击 Next(下一步)。 g. 点击 Import(导入)。 h. 当出现加载成功的消息时,点击 Done(完成)。 现在,在 Classes 页面上,您应该看到 FirstLook.ObjectScript.cls 和 FirstLook.Person.cls 在类的列表中。在 InterSystems IRIS 中,包含类的包名称(FirstLook)附加有类的名称(ObjectScript 或 Person)。扩展名 .cls 用来表示类文件。 注意: 如果您的命名空间包含大量的类,可以在页面左栏的 Class Name(类名) 框中输入 F*.cls 来过滤列表。 ObjectScript 和 Globals 如果您想使用一些 ObjectScript 命令,一个很好的方法是使用 InterSystems 终端(InterSystems Terminal)。(如果您以前没有使用过终端(Terminal),请参见InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》) 中的 "InterSystems IRIS Connection Information(《InterSystems IRIS 连接信息》)"。) 在您启动终端会话(Terminal session)后,提示会指示您处于哪个命名空间。如果您不在 USER 命名空间,执行以下命令: set $namespace = "USER" 试一试:使用 ObjectScript 存储和检索数据 在 ObjectScript 中, 您可以使用 set 命令给变量赋值: USER>set x = "Welcome to ObjectScript!" 要显示一个变量的内容,请使用 write 命令: USER>write x Welcome to ObjectScript! 您刚刚创建的变量只存在于这个终端会话(Terminal session)的工作内存中。如果您想在数据库中存储一个值,您可以使用 global,它看起来像一个带插入符号(^)的变量: USER>set ^Settings("Color") = "Red" Globals 提供持久性存储,这意味着在您关闭终端会话后,^Settings 将继续存在。 这个特殊的 global 也是一个数组,有一个下标。与许多其他语言中的数组不同,globals 可以有整数、小数或字符串等下标。Globals 也是稀疏的,这意味着下标可能是连续的,也可能不是连续的。 您可以利用 globals 的多维特性来定义一个更复杂的结构: USER>set ^Settings("Auto1", "Properties", "Color") = "Red" USER>set ^Settings("Auto1", "Properties", "Model") = "SUV" USER>set ^Settings("Auto2", "Owner") = "Mo" USER>set ^Settings("Auto2", "Properties", "Color") = "Green" 要显示 global 中的所有节点,您可以使用 zwrite 命令: USER>zwrite ^Settings ^Settings("Auto1","Properties","Color")="Red" ^Settings("Auto1","Properties","Model")="SUV" ^Settings("Auto2","Owner")="Mo" ^Settings("Auto2","Properties","Color")="Green" ^Settings("Color")="Red" 要检索存储在 global 特定节点上的值,您可以使用 $get() 函数。如果您试图从不存在的 global 节点检索值,这个函数将返回空字符串,以避免潜在的未定义错误。 在终端(Terminal)尝试以下操作: USER>set ^testglobal(1) = 8888 USER>set ^testglobal(2) = 9999 USER>set globalValue = $get(^testglobal(1)) USER>write "The value of ^testglobal(1) is ", globalValue The value of ^testglobal(1) is 8888 要在 global 中迭代节点,您可以使用 $order() 函数,它返回 global 中的下一个下标。传入一个下标等于空字符串的 global 节点会导致 $order() 返回第一个下标。返回值等于空字符串表示 $order() 已经到达最后一个下标。 您可以像编写变量或 global 的值一样编写函数返回的值: USER>write $order(^testglobal("")) 1 USER>write $order(^testglobal(1)) 2 USER>write $order(^testglobal(2)) USER> 在实践中,您通常会在 ObjectScript 类文件中的类方法中创建一个 $order() 循环。在 FirstLook.ObjectScript.cls 中为您提供了以下方法。 试一试: 使用 ObjectScript 存储和检索数据 /// Iterate over global ^testglobal ClassMethod Iterate() { // Start by setting subscript to "" set subscript = "" // "Argumentless" for loop for { // Get the next subscript set subscript = $order(^testglobal(subscript)) // When we get to the end, quit the for loop quit:(subscript = "") // Otherwise, write the subscript and the value // stored at ^testglobal(subscript) write !, "subscript=", subscript, ", value=", ^testglobal(subscript) } } 请注意,"无参数(argumentless) "的 for 循环没有指定终止条件,如果我们不显式退出该循环,它将永远循环下去。Write 语句中的感叹号告诉 ObjectScript 在编写 global 中每个节点的下标和值之前移动到下一行。 要在终端(Terminal)运行该方法,请输入: USER>do ##class(FirstLook.ObjectScript).Iterate() 这产生了输出: subscript=1, value=8888 subscript=2, value=9999 ObjectScript 和 Objects 您可以使用 ObjectScript 来创建具有方法和属性的类。然后您可以将该类的 objects 实例化。示例类 FirstLook.Person.cls 定义了一个类 Person,然后让您创建该类的实例,如 person John Smith 或 person Jane Doe。 基本的类定义如下所示: Class FirstLook.Person Extends %Persistent { Property FirstName As %String [ Required ]; Property LastName As %String [ Required ]; } Person 类扩展了内置的 InterSystems IRIS 类 %Persistent,它允许您访问父类中一些有用的方法,如 %New() 和 %Save()。 然后列出该类的属性。在这种情况下,您只是了存储一个 person 的名字和姓氏。 继续使用 终端(Terminal)创建一个新 person。如果您不在 USER 命名空间,执行以下命令: set $namespace = "USER" 要创建一个新的 Person object,请使用 %New() 方法,该方法返回一个新 person 的 "句柄",更正式的说法是一个 object 引用,或 OREF。然后设置新 person 的属性,并调用 %Save() 方法将新 person 存储在数据库中。 USER>set person = ##class(FirstLook.Person).%New() USER>set person.FirstName = "Sarah" USER>set person.LastName = "Aarons" USER>set status = person.%Save() USER>write status 1 试一试: 使用 ObjectScript 存储和检索数据 %Save() 方法返回一个状态,如果成功的话,其值为 1。 当您保存一个 object 时,InterSystems IRIS 会自动为您把它储存在一个 global 中。默认的 global 名称是末尾带有 Dappended 的类名,在本例中是 ^FirstLook.PersonD。 如果显示 global 的内容,您可以看到根节点(没有下标的节点)持有一个 ID,这个 ID 对存储的每个新对象来说是递增的。Global 的其余部分由 ID 下标。每个 Person 节点包含一个属性值列表,其中列表用 $lb 表示,用于 "列表构建"。 USER>zwrite ^FirstLook.PersonD ^FirstLook.PersonD=1 ^FirstLook.PersonD(1)=$lb("","Sarah","Aarons") 您还可以定义实例方法,它对特定的实例进行操作,而类方法则是类的泛型方法。例如, FirstLook.Person.cls 包含一个 WriteName() 方法, 该方法编写 person 的名字。 /// Given an instance of a person, write person's name Method WriteName() { write "The name of this person is:" write !, ..FirstName write !, ..LastName } 属性或方法名称前面的额外点表示当前对象或类。 由于变量 person 目前指的是 Sarah Aarons,您可以这样写她的名字: USER>do person.WriteName() The name of this person is: Sarah Aarons 作为练习,创建、存储和编写 Person 类的一些新对象,例如,Andrew Shaw、Peter Shaw 和 Kate Aarons。 ObjectScript 和 SQL 您刚刚已经看到了如何将创建的每个 person 存储为 global 中的节点。正如您将在本节中所看到的,每个 person 也是表中的一行,可以使用 SQL 进行访问。 InterSystems 提供了几种在 ObjectScript 中使用 SQL 的方法。例如,您可以使用类查询,这基本上是类文件中的 SQL 查询。 在 FirstLook.Person.cls 中,下面的类查询,对类中的所有对象执行 SELECT 命令: /// Query for all stored names Query Select() As %SQLQuery [SqlProc] { SELECT %ID, FirstName, LastName FROM Person ORDER By LastName, FirstName } 要测试该查询,您可以从终端(Terminal)运行它: USER>do ##class(%ResultSet).RunQuery("FirstLook.Person", "Select") 输出将显示一个列表,其中包含您在前面的练习中创建并存储的每个 person,按姓氏,然后是名字排序: ID:FirstName:LastName: 4:Kate:Aarons: 1:Sarah:Aarons: 2:Andrew:Shaw: 3:Peter:Shaw: 了解有关 ObjectScript 的更多信息 在实际生活中,您可能会编写一个类方法,比如 FirstLook.Person.cls 中为您提供的方法,将查询的结果放在结果集中,然后遍历这个结果集中的每一行: /// Run select query and write all names in result set ClassMethod WriteAllNames() { // Create a new %SQL.Statement object set stmt = ##class(%SQL.Statement).%New() // Prepare the class query to execute by passing in // the ClassName and QueryName. set status = stmt.%PrepareClassQuery("FirstLook.Person", "Select") // Handle any errors if $$$ISERR(status) { do $system.OBJ.DisplayError(status) quit } // Execute the query set resultSet = stmt.%Execute() // Iterate over results while (resultSet.%Next()) { // Write person's first and last name write !, resultSet.%Get("FirstName"), " ", resultSet.%Get("LastName") } } 在调用 %PrepareClassQuery() 后,这个类方法使用 $$$ISERRmacro 来检查错误状态。然后, 在执行查询后,代码使用 resultSet.%Next() 循环遍历结果集,如果存在另一行,则返回 true。 要在终端(Terminal)运行该方法,请输入: USER>do ##class(FirstLook.Person).WriteAllNames() Kate Aarons Sarah Aarons Andrew Shaw Peter Shaw 正如您所看到的,ObjectScript 为您提供了几个处理数据的选项。使用 globals 可以最大限度地控制数据的存储方式,使用 objects 可以轻松地处理类的单个实例,而 SQL 可以跨表的行进行操作。如何看待数据完全取决于您自己。 了解有关 ObjectScript 的更多信息 使用下面列出的参考资料,了解更多关于 ObjectScript 编程的知识。 ObjectScript 教程 --- 提供 ObjectScript 语言的交互式介绍。 Using ObjectScript(使用 ObjectScript)--- 提供 ObjectScript 编程语言的概述和详细信息。 ObjectScript Reference(ObjectScript 参考资料) --- 提供 ObjectScript 的参考资料。 Orientation Guide for Server-Side Programming(服务器端编程定向指南) --- 为使用 InterSystems 产品编写服务器端代码的程序员提供基本信息。 InterSystems ObjectScript Basics(InterSystems ObjectScript 基础) --- 涵盖 ObjectScript 基础的交互式课程。
文章
Nicky Zhu · 九月 22, 2021

IRIS 2021 技术文档 First Look 2--InterSystems IRIS基础知识:安装

1 安装基础知识:目的 本指南可帮助您成功在桌面或虚拟机上运行一个经授权许可的 InterSystems IRIS®。适用于我们在技术概要 (First Look)操作指南里所提及的技术。我们提供的说明包括64位 Windows 10, Red Hat 企业版Linux7,以及Apple macOS10.13. 注: InterSystems 云管理器(ICM)提供了一种简单、直观的方法来配置云或虚拟基础架构,用户可在该基 础架构上部署所需的 InterSystems IRIS架构以及其他服务。 请勿使用本指南安装生产实例或任何自定义安装配置;如需帮助,请参阅InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)或Installation Guide(《安装指南》)。 2 用前须知 在开始安装 InterSystems IRIS之前,请确保:• 计算机上的完整管理员权限或sudo权限。• 访问InterSystems IRIS的单文件的可执行安装文件(Windows)或工具包(Linux和macOS)。 • 在IRIS可访问的文件夹下存放有效的许可证密钥文件,通常命名为iris.key。 您正在使用的技术概要(First Look)中对安装有特定要求;例如,可能需要“正常”安全性。在遵循以下说 明之前,请务必查看技术概要中“用前须知”章节。 注: 安装了 InterSystems 的IRIS之后,您可以在InterSystems IRIS Basics: Connecting an IDE (《InterSystems IRIS基础:连接一个IDE》)中,查找介绍如何将一个IDE连接到InterSystems IRIS上的实例过程。 3 在Windows10系统安装 InterSystems IRIS 要在Windows10上安装 InterSystems IRIS: 在Windows资源管理器中,右键单击 InterSystems IRIS安装可执行文件,然后选择“Run as administrator(以管理员身份运行)”。在生成的Windows用户帐户控制对话框中,选择“YES”。 如果出现“Select instance(选择实例)”对话框,请选择“New Instance(新建实例)”。 勾选接受许可协议,然后单击“Next(下一步)”。 在“InterSystems IRIS Instance Name(InterSystems IRIS实例名称)”对话框中为你的实例起 名,InterSystems IRIS实例名称仅可使用字母数字字符和下划线。然后单击“Next(下一步)”。 如果目标文件夹显示可安装,请单击“Next(下一步)”。如不可安装,请单击“Change(更改)”以选 择其他文件夹。请使用计算机上的文件夹,而不是映射的网络驱动器。 在“Setup Type(安装类型)”对话框中,接受默认的Development,然后单击“Next(下一步)”。 在“Initial Security Settings(初始安全设置)”对话框中,选择技术概要(First Look)中所推荐的 安全类型。通常应选用Normal(正常)类型。如未找到推荐的安全类型,请使用Minimal(最小值),然后 单击“Next(下一步)”。 (仅限正常和锁定安全类型)在“Enter Credentials(输入凭据)”对话框中,选择在defined Username account(定义的用户名账号)下运行InterSystems IRIS,确认Windows用户名和域名正确,并输入 Windows密码。然后单击“Next(下一步)”。 (仅限正常和锁定安全类型)在InterSystems IRIS Users configuration(InterSystems IRIS用户配 置)对话框中,输入并再次确认8-32个字符的密码(允许使用字母数字和标点符号)。请注意此密码将在 登录InterSystems IRIS主要管理工具(management tools)时使用。然后单击“Next(下一步)”。 (仅限正常和锁定安全类型)输入CSPSystem Account的密码时(Enter password for CSPSystem account),请输入并再次确认8-32个字符的密码(允许使用字母数字和标点符号)。请记住此密码。然后 单击“Next(下一步)”。 在“Ready to Install the Program(准备安装程序)”对话框中,单击“License(许可证)”,然后选 择许可证密钥文件。然后单击“Install(安装)”,此安装过程需要几分钟时间。 要访问新安装,请右键单击上箭头 4 在Linux系统安装 InterSystems IRIS 在Linux系统上安装 InterSystems IRIS须知: 在Linux中创建一个组,并添加您的用户账号。 提取安装文件。 跳转至安装文件。 运行命令“sudo ./irisinstall”,它将出现一系列提示 如果系统提示您要输入平台的编号,请输入为Red Hat Enterprise Linux列出的编号。 “Enter instance name(输入实例名称)”,请输入用户名。仅使用字母数字字符和下划线。 按Enter键确认名称。 “Enter a destination directory for the new instance(为新实例输入目标目录)”,请输入 InterSystems IRIS系统文件的目录名称,您的计算机上不存在目录,不要使用符号链接 (symlink)。 按Enter确认需要创建的新目录(或使用输入的现有目录)。 “Setup type<1>(安装程序类型<1>)”,按Enter键接受默认安装类型(Development)。 “Initial Security settings(初始安全设置)”,请输入技术概要(First Look)中所推荐的安全 类型的编号,通常应选择Normal(正常)类型。如果没有,请按Enter接受默认值1(Minimal)。 (仅限正常和锁定安全类型)“Which user should be the owner of this instance?(本实例的用户 是?)”请输入您的用户账户名称。 (仅限正常和锁定安全类型)“Please enter the common password for _SYSTEM...(请输入 _SYSTEM...的通用密码)”,输入(然后再次确认)8-32个字符的密码(允许使用字母数字和标点符 号)。请注意此密码,因为您将在登录到InterSystems IRIS主要管理工具(management tools)时使 用此密码。 (仅限正常和锁定安全类型)“Please enter the common password for CSPSystem...(请输入 CSPSystem...的通用密码)”,输入(然后再次确认)8-32个字符的密码(允许使用字母数字和标点 符号)。请记住此密码。 “What group should be allowed to start and stop this instance?(应该允许哪个组启动和停 止此实例?)”请输入您在上面的步骤1中创建的组的名称。 “Do you want to enter a license key(您是否需要输入一个license key?)”输入y,然后输入许 可证密钥的完整路径名(例如, /home/user/iris/iris.key)。 该脚本会显示您在继续之前选择的安装选项。按Enter键选择继续安装。 请注意安装结束时显示的URL:它是管理门户(Management Portal)的URL,也是 InterSystems IRIS的系 统管理用户界面。 要检查新安装实例的状态并查看其他信息,请在Linux命令行下输入“iris list”查看实例列表。 5 在macOS系统安装InterSystems IRIS 要使用bashshell在macOS上安装 InterSystems IRIS: 在macOS中创建一个组,并添加您的用户账户。 提取安装文件。 跳转至安装文件。 运行命令“sudo ./irisinstall”,它将出现一系列提示。 如果系统提示您要输入平台的编号,请输入macOS列出的编号。 “Enter instance name(输入实例名称)”,请输入用户名。仅使用字母数字字符和下划线。 按Enter键确认实例名称。 “Enter a destination directory for the new instance(为新实例输入目标目录)”请输入 InterSystems IRIS系统文件的目录名称,您的计算机上不存在目录,不要使用符号链接 (symlink)。 按Enter确认需要创建的新目录(或使用输入的现有目录)。 “Setup type<1>(安装程序类型<1>)”,按Enter键接受默认安装类型(Development)。 “Initial Security settings(初始安全设置)”,请输入技术概要(First Look)中所推荐的安全 类型的编号。通常应选择Normal(正常)安全类型。如果没有,请按Enter接受默认值1(Minimal)。 (仅限正常和锁定安全)“Which user should be the owner of this instance?(本实例的用户 是?)”请输入您的用户账户名称。 (仅限正常和锁定安全类型)“Please enter the common password for _SYSTEM...(请输入 _SYSTEM...的通用密码)”,输入(然后再次确认)密码(包含字母和数字)。请注意此密码,因为 您将在登录到主要InterSystems IRIS管理工具(management tools)时使用此密码。 (仅限正常和锁定安全类型)“Please enter the common password for CSPSystem...(请输入 CSPSystem...的通用密码)”,输入(然后再次确认)密码(包含字母和数字)。请记住此密码。 “What group should be allowed to start and stop this instance?(应该允许哪个组启动和停 止此实例?)”请输入您在上面的步骤1中创建的组的名称。 “Do you want to enter a license key(您是否需要输入一个license key?)”输入y,然后输入许 可证密钥的完整路径名(例如, /home/user/iris/iris.key)。 该脚本会显示您在继续之前选择的安装选项。按Enter键选择继续安装 请注意安装结束时显示的URL:它是管理门户(Management Portal)的URL,也是 InterSystems IRIS的系统管理用户界面。 要检查新安装实例的状态并查看其他信息,请进入 命令行并输入“iris list”查看实例列表。
公告
Claire Zheng · 九月 15, 2021

Online Meetup:与InterSystems开发者竞赛(InterSystems IRIS Analytics)竞赛优胜者交流

亲爱的社区开发者们,大家好! 我们诚挚地邀请您参加与InterSystems开发者竞赛(InterSystems IRIS Analytics)竞赛优胜者交流 online meetup! 日期 & 时间: 美国东部时间2021年9月17日(周五)12:00;北京时间2021年9月18日(周六)0:00-1:00 在此次线上交流会上,您将了解到: 优胜者简介 优胜者提交项目的简短demo 关于项目中使用到的技术的开放探讨、问答,以及下一场开发者竞赛的安排。 届时上线嘉宾: @Dmitry.Maslennikov, Co-founder, CTO and Developer Advocate, CaretDev Corp @Henry.HamonPereira, Systems Analyst at BPlus Technology @Evgeniy.Potapov, CEO at TECCOD @John Pan, @Carmen.Logue, InterSystems Product Manager - Analytics and AI @Evgeny.Shvarov, InterSystems Developer Ecosystem Manager 您还有机会在这个特别的线上研讨会中与我们的开发者交流。 期待您的参加! ➡️ 注册参会!
公告
Claire Zheng · 九月 15, 2021

InterSystems开发者竞赛(InterSystems IRIS Analytics)优胜者已产生!他们是……

亲爱的社区开发者们,大家好! InterSystems 开发者竞赛(InterSystems IRIS Analytics) 现已圆满结束!感谢大家的参与支持! 现在是揭晓优胜者的时刻了! 这些开发者和他们的应用程序赢得了雷鸣般的掌声: 🏆 专家提名奖(Experts Nomination)- 获奖者由我们特别挑选的专家团选出: 🥇 第一名,奖金 $4,000,获奖项目 promjet-stats ,作者 @Evgeniy.Potapov 🥈 第二名,奖金 $2,000,获奖项目 iris-analytics-datastudio ,作者 @Dmitry.Maslennikov 🥉 第三名,奖金 $1,000,获奖项目 pop-song-analytics,作者 @Henry.HamonPereira 🏆 社区提名奖(Community Nomination)- 获得总投票数最多的应用: 🥇 第一名,奖金 $1,000,获奖项目 iris-analytics-datastudio ,作者@Dmitry.Maslennikov 🥈 第二名,奖金 $500,获奖项目 AlertDashboard ,作者 @John Pan 🥉 第三名,奖金 $250,获奖项目 promjet-stats ,作者@Evgeniy.Potapov 恭喜所有优胜者! 感谢大家对本次比赛的关注和付出! 恭喜中国参赛者 @John Pan荣获此次竞赛“社区提名奖(Community Nomination)”第三名